#java #jms #activemq #jms-topic
#java #jms #activemq #jms-тема
Вопрос:
Я недавно работаю с темой в jms, и у меня проблема. Мой TopicSubscriber не получил сообщение от издателя, и я не понимаю, почему.
Вот мой TopicPublisher:
public class Publisher
{
private static final String CONNECTION_URL = "tcp://localhost:61616";
public static void main(String[] args) throws Exception
{
BrokerService service = BrokerFactory.createBroker(new URI("broker:(" CONNECTION_URL ")"));
service.start();
TopicConnectionFactory connectionFactory = new ActiveMQConnectionFactory(CONNECTION_URL);
// create a topic connection
TopicConnection topicConn = connectionFactory.createTopicConnection();
// create a topic session
TopicSession topicSession = topicConn.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
// lookup the topic object
Topic topic = topicSession.createTopic("test");
// create a topic publisher
TopicPublisher topicPublisher = topicSession.createPublisher(topic);
topicPublisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// create the "Hello World" message
TextMessage message = topicSession.createTextMessage();
message.setText("Hello World");
// publish the messages
topicPublisher.publish(message);
// print what we did
System.out.println("Message published: " message.getText());
// close the topic connection
topicConn.close();
}
}
Мой подписчик темы:
public class Subscriber
{
private static final String CONNECTION_URL = "tcp://localhost:61616";
public static void main(String[] args) throws Exception
{
TopicConnectionFactory connectionFactory = new ActiveMQConnectionFactory(CONNECTION_URL);
// create a topic connection
TopicConnection topicConn = connectionFactory.createTopicConnection();
// create a topic session
TopicSession topicSession = topicConn.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE);
Topic topic = topicSession.createTopic("test");
// create a topic subscriber
TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
// start the connection
topicConn.start();
// receive the message
TextMessage message = (TextMessage) topicSubscriber.receiveNoWait();
// print the message
System.out.println("Message received: " message.getText());
// close the topic connection
topicConn.close();
}
}
В моем подписчике у меня есть указатель NULL на message.getText()
В чем эта проблема? Что я делаю не так и как это можно исправить?
Комментарии:
1. Вы уверены
NullPointerException
, что включенtopicSubscriber.receiveNoWait()
? Это указывалоtopicSubscriber
бы на isnull
. Кажется более вероятным, чтоNullPointerException
это происходит изmessage.getText()
-за того, чтоmessage
естьnull
. Пожалуйста, подтвердите.2. Да, я имею в виду, что message.getText() имеет значение null. Но это потому, что подписчик не получил сообщение. И я не понимаю, почему
Ответ №1:
Похоже, что вы отправляете сообщение перед созданием подписки. Темы JMS используют семантику публикации-подписки, где любое опубликованное сообщение распространяется на все подписки. Если подписок нет, сообщение отбрасывается.
Кроме того, поскольку вы используете receiveNoWait()
, вы сильно снижаете вероятность того, что ваш клиент когда-либо получит сообщение. Для того, чтобы ваш клиент действительно получил сообщение, сообщение должно быть отправлено между временем, когда вы звоните createSubscriber(topic)
, и временем, когда вы звоните receiveNoWait()
. Поскольку эти 2 вызова происходят очень близко друг к другу, интервал времени очень мал.
Если вы действительно хотите, чтобы ваш подписчик получил сообщение Subscriber
, сначала запустите и используйте receive()
receiveNoWait()
, а не затем запустите Publisher
. Это гарантирует, что подписка существует при отправке сообщения и что клиент ожидает получения сообщения перед завершением.