Spring JMS Subscriber not able to receive message? - java

I'm using Spring JMS and Web Sphere Default Messaging Provider for my Messaging Needs.
I have created a Topic and connection factory on WAS.
I am able to send message to Topic using JMSTemplate from my publisher.
But Whenever I call JmsTemplate.receive() in my Subscriber , it goes into waiting state and I am not able to receive message in my Subscriber.
However I am able to receive message in Subscriber using JmsTemplate if a use a Listener as Subscriber or if a start a new thread whenever I am publishing message using my Publisher.
Looking for help !

Messages are not stored in the topic. If you create a Publisher, send messages ans then start a subscriber no messages will be subscribed. At the time of publishing if there are any subscribers subscribed to that topic then only those subscribers will receive the message. If no subscribers exist then messages will be dropped.
It goes into waiting state that means it is waiting for messages from the JMS server and there are no currently available.
Whatever mode of subscribing you are using - asynchronous(MessageListener) or Synchronous(receive) you need to create subscriber before.
You can use
subscriber.receive(long timeout);
if you do not want to wait indefinitely.

Related

Mqtt Client: get Retained Message after Subscribing

I am using the latest Paho version via Maven.
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<version>1.2.2</version>
</dependency>
I create client using
MqttClient client = new MqttClient("tcp://localhost", MqttClient.generateClientId());
MqttConnectOptions options = new MqttConnectOptions();
options.setMaxInflight(1000);
options.setAutomaticReconnect(true);
Then I subscribe to a topic as follows:
client.setCallback(new Callback());
client.connect();
client.subscribe(topic);
Another mqtt client publishes a message on that topic with
MqttMessage message = new MqttMessage(byteStream);
message.setRetained(true);
With the retain flag I would expect that as soon as I subscribe, my callback is invoked. Unfortunately, the subscription callback is NOT called if the message is sent before the subscription is executed.
How do I get the retained value?
I think you are using QOS=0.
It is possible a retained message not saved with QOS=0 and retained_flag=true.
More details:
Reference link:
SECTION (3.3.1.3 RETAIN):
If the RETAIN flag is set to 1, in a PUBLISH Packet sent by a Client to a Server, the Server MUST store the Application Message and its QoS, so that it can be delivered to future subscribers whose subscriptions match its topic name [MQTT-3.3.1-5]. When a new subscription is established, the last retained message, if any, on each matching topic name MUST be sent to the subscriber [MQTT-3.3.1-6].
If the Server receives a QoS 0 message with the RETAIN flag set to 1 it MUST discard any message previously retained for that topic. It SHOULD store the new QoS 0 message as the new retained message for that topic, but MAY choose to discard it at any time - if this happens there will be no retained message for that topic [MQTT-3.3.1-7]. See Section 4.1 for more information on storing state.
Summary:
You can use QOS>0 to solve your problem.
Unfortunately, the subscription callback is NOT called if the message is sent before the subscription is executed. How do I get the retained value?
In this case, the publisher (one client) sends out message, immediately disconnects from MQTT broker (server), then the subscriber (another client) connects to the server with the same topic, Without last will message, it is not possible that the published message will be delivered to your subscriber.
There would be options in paho to enable last will message by setting :
will flag
will retain flag
will topic
will message (will payload)
retain flag in PUBLISH control packet (not the same as will retain flag)
Set up all of them when the publisher sends out the message with a topic, the sent message will be retained on MQTT broker even after the publisher closes network connection. At a later time when any subscriber (another client) connects to the broker with the same topic, the retained message will be sent from the broker to the subscriber.
Also please note that QoS field of PUBLISH control packet is for ensuring delivery is complete (at different level) ONLY between MQTT publisher and MQTT broker(server) , NOT between MQTT publisher and subscriber (the 2 clients).

Apache Camel jms ack message delivery notification

Looking for possibility to get camel jms ack delivery notification.
So - I want to notify producer when message is delivered on server (not when consumer is received).
Possible solution:
CompletableFuture<Exchange> future = template.asyncSend(uri, exchange, synchronisation);
In this case synchronisation onComplete method triggered when consumer received.
The same with future get.
I want to detect moment when message is delivered on jms server and if it is delivered.
Thank you

How do durable subscribers work with JMS?

So I am creating concurrent consumers to a topic i.e. multiple listeners. I am configuring them to be durable.
#Bean
public DefaultMessageListenerContainer listenerContainers() {
DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
container.setConnectionFactory(connectionFactory());
container.setDestinationName(COMMENT_QUEUE);
container.setPubSubDomain(true);
container.setSessionTransacted(true);
container.setConcurrentConsumers(2);
container.setSubscriptionDurable(true);
container.setMessageListener(datafileSubscriber);
container.start();
return container;
}
What I want to know is,
Lets suppose a event came and it is published to all 5 subscribers. One of them processes it, so it doesnt immediately acknowledge until the process is done but remaining 4 immediately acknowledge because they are idle.
Lets suppose a second event came, Now
Is it sent to 4 subscribers and keeps the message in queue for 5th subscriber and sends it to 5th subscriber only after it gives a acknowledgement?
OR
It doesnt send to any of the message subscribers but waits in the queue until the 5th subscriber also acknowledges and then sends out to all the subscribers at a time?
I am using setsessiontransacted true.
What happens now 1 or 2 ?
Also I am assuming the broker maintains an internal queue for each concurrent subscriber to understand the flow of messages to that durable subscriber.
Can someone explain how the flow works for the configuration of concurrentconsumer, durable subscription and setsessiontransacted=true?
Messaging provider will put the event messages into subscriber's subscription queue as and when they are published. It is the subscribers who pull (or receive using listeners) those messages from their subscription queue. So if a subscriber is busy processing an event message, other subscribers are not affected at all, they will continue to receive publications. In fact subscribers won't know the presence of other subscribers.

RabbitMQ receiver need to check for new message in queue

I am using spring and Hibernate with RabbitMQ.
I am facing problem that when sender send message to receiver(consumer) that time message add to queue successfully but receiver have to check every time to get new message from queue.
This is increasing overhead.
Is there any proper solution using that receiver automatic knows that new message in a queue.

Acknowledge a message from a different Channel/Session in JMS

I need a message to be Acknowledged in a different Session than the one it is created in. If the consumed message is not ACKed in a given time, it should be added back to the queue. Is this possible using JMS( planning to use ActiveMQ as the broker).
I don't think it is possible.
If the message is consumed, it should be acknowledged by the consumer session (it can be auto or client acknowledgement). Acknowledgment is the key for guaranteed messaging and transaction mechanism. JMS server ensures the message is sent/consumed successfully using acknowledgement.
Regarding timeout question, if the JMS server didn't receive the ack in given time period, the message will be redelivered usually with JMSRedelivered flag set. I don't think it will be added back to the Queue then able to be consumed by same session or another session as a new message.

Categories