是否可以在没有倒计时的情况下编写JMS接收器

时间:2011-08-16 06:21:26

标签: jms

我是JMS的新手。如果我的问题没有意义,请纠正我。 我正在编写一个使用jms发送对象的程序。但是在我的程序中,我不时发送的对象数量是不同的。所以我不能在接收方使用倒计时。虽然我经常搜索,但我也无法找到了解JMS队列长度的方法。 因此,请指导我如何阅读我的队列,直到消耗掉所有对象为止。

下面是我的代码,它只读取队列的第一个对象

public class QReciever{

private static QueueConnection qConn;
private static QueueSession qSession;
private static Queue que;

private static BuildInfo recieveBuildInfo;


///INner Class

public static class ExListener implements MessageListener{
    public void onMessage(Message msg){
        System.out.println("IN side onMessage method in Inner class");
        try {
            ObjectMessage objMsg = (ObjectMessage) msg;
            setRecieveBuildInfo((BuildInfo)objMsg.getObject());
            System.out.println("############################ Inside the Inner class\n\t Build No is: "+getRecieveBuildInfo().getBuildNo());
            write2Db(getRecieveBuildInfo());

        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}



public static BuildInfo getRecieveBuildInfo() {
    return recieveBuildInfo;
}
public static void setRecieveBuildInfo(BuildInfo recieveBuildInfo) {
    QReciever.recieveBuildInfo = recieveBuildInfo;
}



public static void recieveQueue() throws Exception{
    System.out.println("############################Inside recieveQueue");  //####################################################################

//Jndi lookup   
    Properties props = ProptManager.getProperties();

    InitialContext initCtx = new InitialContext(props);
    Object temp = initCtx.lookup("XAConnectionFactory");
    QueueConnectionFactory qcf = (QueueConnectionFactory) temp;
    qConn = qcf.createQueueConnection();
    qConn.start();
    que = (Queue) initCtx.lookup("queue/MyQueue");
    qSession = qConn.createQueueSession(false, qSession.AUTO_ACKNOWLEDGE);
    QueueReceiver qReciever = qSession.createReceiver(que);

    qReciever.setMessageListener(new ExListener());



    qReciever.close();
    System.out.println("qReciever Closed");
    qSession.close();
    System.out.println("qSession Closed");
    qConn.close();
    System.out.println("qConn Closed");
    //System.exit(1);
}

public static void write2Db(BuildInfo bInfo){
    System.out.println("############################  Inside write2Db ");
                 //writing to the database
    }catch(Exception e){
        System.out.println("Error: Updating Database, The record which the Build No is: "+bInfo.getBuildNo()+" may already inserted" + e.getMessage());

    }
}

3 个答案:

答案 0 :(得分:0)

据我所知,没有直接的方法可以做到这一点。但是有两种(可能更多......)方法可以做到这一点。虽然我认为他们中的大多数都是相当低效/缓慢的...... /。

如果我理解正确,您可以批量发送,即您每天或每小时发送数据一小段时间。我的解决方案'如果连续发送,则不起作用。

您可以做什么,具体取决于您的JMS实施(如果您愿意做某些特定事情):您可以使用JMX(例如,如果您的JMS提供商提供它,SonicMQ会这样做),以查明是否存在是队列中的任何其他消息。

或者您可以创建一个单独的QueueBrowser,以查看是否还有其他消息。

也许你可以添加更多关于你的用例的信息,所以我们知道为什么你需要知道该队列中是否有更多的消息。

我认为QueueBrowser是最容易做到的事情,但我认为它既不优雅也不高效,你可能想找到一个不同的解决方案。

希望这有帮助。

答案 1 :(得分:0)

我认为您最好的选择是在您正在使用的JMS队列上添加另一个协议。

如果您有单个生产者和单个消费者,您可以让生产者首先发送包含要发送的消息总数的标头消息,并且最后发送预告消息不再发送消息。这将允许您显示计数并检测任何丢失的消息。

但我不认为这是一个很好的队列使用。对于队列,您通常希望每条消息都是独立的。对于消费者来说,有多少消息已经到达,它应该尽可能盲目地处理单个消息。

答案 2 :(得分:0)

我只是在最后一条消息上设置一个布尔属性,表明你已经完成了。