【问题标题】:Glassfish & JMS: Why do published messages not arrive at subscribers?Glassfish & JMS:为什么发布的消息没有到达订阅者?
【发布时间】:2012-05-01 12:25:48
【问题描述】:

我有一个 Glassfish 3.1.2 服务器在远程机器 (JDK 1.6.0_30) 上运行。以下代码是在 Java SE 环境中运行的独立客户端,使用 JNDI 查找连接到 JMS。客户端同时是发布者和订阅者。

我创建的JMS连接池和主题如下:

./asadmin create-jms-resource --restype javax.jms.ConnectionFactory jms/TopicConnectionFactory
./asadmin create-jms-resource --restype javax.jms.Topic jms/TopicUpdate

我启动了这个客户端的两个实例。消息似乎已传递 - 没有错误 - 但消息没有到达订阅者...

我做错了什么?

任何帮助表示赞赏 - 非常感谢提前!

public class JMS implements MessageListener {

    private TopicConnectionFactory factory;
    private TopicConnection connection;
    private Topic topic;

    private void subscribe() {
        try {
            System.setProperty("org.omg.CORBA.ORBInitialHost", "192.168.1.6");
            System.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
            InitialContext ctx = new InitialContext();
            factory = (TopicConnectionFactory)ctx.lookup("jms/TopicConnectionFactory");
            topic = (Topic)ctx.lookup("jms/TopicUpdate");
            connection = factory.createTopicConnection();
            TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
            TopicSubscriber subscriber = session.createSubscriber(topic);
            subscriber.setMessageListener(this);
            connection.start();
            while(true) {
                Thread.sleep(5000);
                sendMessage();
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(JMS.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NamingException ex) {
            Logger.getLogger(JMS.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JMSException ex) {
            Logger.getLogger(JMS.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void sendMessage() {
        try {
            TopicSession session = connection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
            TopicPublisher publisher = session.createPublisher(topic);
            TextMessage message = session.createTextMessage();
            message.setText("Message from client.");
            publisher.send(message);
            session.close();
            System.out.println("Message sent.");
        } catch (JMSException ex) {
            Logger.getLogger(JMS.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void onMessage(Message msg) {
        System.out.println("Message received.");
    }

    public JMS() {
        subscribe();
    }

    public static void main(String[] args) {
        new JMS();
    }

}

【问题讨论】:

    标签: java glassfish jms mq


    【解决方案1】:

    当您在创建会话时使用 true 作为第一个参数时,确认模式将被忽略,并假定您已进行交易。尝试将第一个参数设为 false。

    就这么清楚了,修改这行代码:

    TopicSession session = connection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
    

    成为:

    TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
    

    在您的发送消息方法中。

    【讨论】:

    • 嘿约翰,非常感谢这个提示!它现在工作得很好:-)!
    【解决方案2】:

    最好让发布者和订阅者不同。我

    这里是如何使用 Spring JMS 模板订阅的代码。

    public class MsgReader implements
            SessionAwareMessageListener<Message> {
    
        @Override
        public void onMessage(Message message, Session session) throws JMSException {
            if (message instanceof TextMessage) {
                try {
                    System.out.println(((TextMessage) message).getText());
    
                } catch (JMSException ex) {
                    throw new RuntimeException(ex);
                }
            } else {
                throw new IllegalArgumentException(
                        "Message must be of type TextMessage");
            }
        }
    }
    
    • Spring Bean 文件。

    • 最后加载 bean。

      公共类 SpringJMSTest {

      /**
       * @param args
       */
      public static void main(String[] args) {
          ApplicationContext context = new FileSystemXmlApplicationContext(new String[]{"/resource/consumerBean.xml"});
              }
      }
      
    • 现在您将开始在控制台中接收消息。

    【讨论】:

    • 感谢您的回复。我已将我的客户端类拆分为发布者和订阅者类,并将 MessageListener 提取到它自己的类中。但这没有什么区别。还有什么想法吗?
    • 在我看来,您使用的配置或主机端口存在问题(默认情况下,GF JMS 端口为 7676)。为什么不通过 glass fish 管理控制台创建 JMS 目的地和连接工厂.. 对于管理控制台,您需要:- gfserver-ip:4848
    • 这应该没有任何区别。我尝试在 web-gui 上创建连接工厂和资源,但随后将资源复制到连接工厂文件夹。当试图选择它时,它会在 web-gui 上引发一个“错误”。似乎是一个错误......无论如何,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2017-11-08
    • 2018-03-14
    • 2019-03-27
    • 1970-01-01
    • 2017-06-25
    • 2016-06-17
    • 2018-08-14
    • 1970-01-01
    相关资源
    最近更新 更多