【问题标题】:Why my subscriber cant read the message from the publisher on jms为什么我的订阅者无法在 jms 上阅读来自发布者的消息
【发布时间】:2012-11-27 12:29:19
【问题描述】:

我刚开始使用 JMS 所以我拿了一个 example ,它就像一个魅力! 当我在控制台中输入消息时,订阅者收到了它,但该示例仅基于一个文件,因此我决定将其拆分为发布者文件和订阅者文件 但它不起作用,订阅者不阅读消息! 我从this other example 插入了一些代码,但仍然没有,我无法理解为什么我的程序编译完美而没有错误,有人知道为什么它没有读取消息吗?

我的 Subscriver.java 文件是:

package main;
import java.util.Properties;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.sun.messaging.Destination;
public class Subscriver1 {
private TopicSession subSession;
private TopicSubscriber subscriver;
private TopicConnection connection;
private String username;
Destination dest;

public Subscriver1(String topicName, String username, String password)
        throws NamingException, JMSException {
    Properties env = new Properties();
    InitialContext jndi = new InitialContext(env);
    TopicConnectionFactory conFactory = (TopicConnectionFactory) jndi
            .lookup("topicConn");
    TopicConnection connection = conFactory.createTopicConnection(username,
            password);
    TopicSession subSession = connection.createTopicSession(false,
            Session.AUTO_ACKNOWLEDGE);
    Topic chatTopic = (Topic) jndi.lookup(topicName);
    TopicSubscriber subscriver = subSession.createSubscriber(chatTopic,
            null, true);
    Destination dest = (Destination) jndi.lookup(topicName);

    set(connection, subSession, subscriver, username, dest);
    connection.start();
}

private void set(TopicConnection connection2, TopicSession subSession2,
        TopicSubscriber subscriver2, String username2, Destination dest2) {
    this.connection = connection2;
    this.subSession = subSession2;
    this.subscriver = subscriver2;
    this.username = username2;
    this.dest = dest2;
}

public void close() throws JMSException {
    connection.close();
}

public void read() throws JMSException {

    while (true) {
        MessageConsumer consumer = subSession.createConsumer(dest);
        ;
        Message m = consumer.receive(1);

        if (m != null) {
            if (m instanceof TextMessage) {
                TextMessage message = (TextMessage) m;
                System.out.println("Reading message: " + message.getText());
            } else {
                break;
            }
        }
    }
}

public void onMessage(Message message) {
    try {
        TextMessage textMessage = (TextMessage) message;
        String text = textMessage.getText();
        System.out.println(text);
    } catch (JMSException jmse) {
        jmse.printStackTrace();
    }
}

public static void main(String[] args) throws NamingException, JMSException {
    Subscriver1 lexoMesazhin = new Subscriver1("kanaliTopic", "user",
            "user");
    lexoMesazhin.read();
    lexoMesazhin.close();
}

}

我的文件 Publisher.java 文件是

package main;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import javax.jms.TopicConnection;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicPublisher;
import javax.jms.TopicSession;
import javax.naming.InitialContext;
 import javax.naming.NamingException;

public class Publisher {
private TopicSession pubSession;
private TopicPublisher publisher;
private TopicConnection connection;
private String username;

public Publisher(String topicName, String username, String password)
        throws NamingException, JMSException {
    Properties env = new Properties();
    InitialContext jndi = new InitialContext(env);
    TopicConnectionFactory conFactory = (TopicConnectionFactory) jndi
            .lookup("topicConn");
    TopicConnection connection = conFactory.createTopicConnection(username,
            password);
    TopicSession pubSession = connection.createTopicSession(false,
            Session.AUTO_ACKNOWLEDGE);
    Topic chatTopic = (Topic) jndi.lookup(topicName);
    TopicPublisher publisher = pubSession.createPublisher(chatTopic);
    set(connection, pubSession, publisher, username);
    connection.start();

}

private void set(TopicConnection connection2, TopicSession pubSession2,
        TopicPublisher publisher2, String username2) {
    this.connection = connection2;
    this.pubSession = pubSession2;
    this.publisher = publisher2;
    this.username = username2;
}

protected void createMesage(String text) throws JMSException {
    TextMessage mesazhi = pubSession.createTextMessage(text);
    mesazhi.setText(username + " >> " + text);
}

public void close() throws JMSException {
    connection.close();
}

public static void main(String[] args) throws NamingException,
        JMSException, IOException {
    Publisher dergonMesazhin = new Publisher("kanaliTopic", "andi", "andi");
    BufferedReader commandLine = new java.io.BufferedReader(
            new InputStreamReader(System.in));
    try {
        while (true) {
            String s = commandLine.readLine();
            if (s.equalsIgnoreCase("exit")) {
                dergonMesazhin.close();
                System.exit(0);
            } else
                dergonMesazhin.createMesage(s);
        }
    } catch (IOException e) {

    }
}

}

【问题讨论】:

    标签: java jms message publish-subscribe


    【解决方案1】:

    您忘记发布消息,即您应该在createMesage 方法中添加调用publisher.publish(message)。目前,您只是创建一个 TextMessage 对象而不将其发送到任何地方,所以从技术上讲,这在您的订阅者中不是问题,而是在您的生产者中:)

    【讨论】:

    • 感谢您的回复,但仍然没有,订阅者不会收到消息:/
    • 再次尝试后,仍然没有。然后我尝试在netbeans上运行这个东西,它工作了,可能是一个eclipse错误,无论如何谢谢你的回复,感谢你的观察,现在我可以运行我的了代码:)
    【解决方案2】:

    您的 JNDI 服务器位于何处?您将一个空的 Properties 对象传递给 InitialContext。

    Properties env = new Properties();
    InitialContext jndi = new InitialContext(env);
    

    您应该在属性对象中放置一些合理的值,例如服务器 url 等,具体取决于托管 JNDI 服务的服务器。

    也可以尝试省略传递 env 并简单地调用 new InitialContext ();这将从类路径上的文件中读取正确的属性(应该在 glassfish 中)。

    【讨论】:

    • 虽然这是我的第一个,但它似乎适用于 glassfish 3.1,我已经用 oreilly 示例尝试过,它有效,所以我认为问题不存在
    • 我很确定您至少需要定义 InitialContextFactory,例如像这样: env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); docs.oracle.com/cd/E19879-01/821-0029/aeqbg/index.html
    猜你喜欢
    • 2012-05-01
    • 1970-01-01
    • 2018-03-14
    • 2018-08-14
    • 2013-12-06
    • 2010-11-17
    • 2016-06-17
    • 2017-11-08
    • 1970-01-01
    相关资源
    最近更新 更多