Chillax
Chillax

Reputation: 4738

JMS message flow between Sender/Receiver

If I use the following code to create a sender and receiver

qsender = qsession.createSender((Queue)msg.getJMSDestination());
qreceiver=qsession.createReceiver((Queue)msg.getJMSDestination());

and then do this

qsender.send(msg);

Does it just send the message to the queue and will it remain in the queue forever? Do I need to call the receive() method on the receiver or implement the MessageListener interface to get it to the receiver?

Edit: more info

qsender = qsession.createSender((Queue)msg.getJMSDestination());
qreceiver=qsession.createReceiver((Queue)msg.getJMSDestination());

temp1 = qsession.createTemporaryQueue();
responseConsumer = qsession.createConsumer(temp1);
msg.setJMSReplyTo(temp1);

responseConsumer.setMessageListener(responseListener);
msg.setJMSCorrelationID(msg.getJMSCorrelationID()+i);

qsender.send(msg);

In the above code, what is the temporary queue used for? Is it for receiving the messages? Is it the receiver? And if yes, whats the use of msg.setJMSReplyTo(temp1) ?

Upvotes: 1

Views: 5688

Answers (2)

dimas
dimas

Reputation: 6073

Yes, send(..) method will send message to the destination queue. And this message will remain in the queue until your program will receive it using receiver or until your message broker is running (as I know).

About your second question then the difference between two approaches consist in next:

receive(..) method is synchronous (and this is a downside of this approach). This means that the receiver must wait patiently for the message to arrive, as the receive() message will block until a message is available (or until a timeout condition occurs). From other side consuming messages with listener is asynchronous process. Your receiver will not wait. Listener will call your receiving method only when message will be put to the query.

UPDATE:

Temporary destination is used for sending a reply on a message by consumer. For example can be situation that your server get message from client and you need to send response to him. In such case you should use temporary destination. Server application will use this temporary destination (queue in your case) for sending a response message to client. Such queues have a scope limited to the connection that created it, and are removed on the server side as soon as the connection is closed.

More details you can find in this article and in officila java tutorial. In second article also describes how and when to use JMSCorrelationID.

Here is interesting part from official doc that describes how to send response message using temporary destination:

You can use temporary destinations to implement a simple request/reply mechanism. If you create a temporary destination and specify it as the value of the JMSReplyTo message header field when you send a message, then the consumer of the message can use the value of the JMSReplyTo field as the destination to which it sends a reply. The consumer can also reference the original request by setting the JMSCorrelationID header field of the reply message to the value of the JMSMessageID header field of the request. For example, an onMessage method can create a session so that it can send a reply to the message it receives. It can use code such as the following:

producer = session.createProducer(msg.getJMSReplyTo());
replyMsg = session.createTextMessage("Consumer " +
    "processed message: " + msg.getText());
replyMsg.setJMSCorrelationID(msg.getJMSMessageID());
producer.send(replyMsg);

UPDATE 2:

I want to clarify my unswer about message expiration time in the queue (or topic). By default message will never expire. But you can set expiration time for message:

producer.setTimeToLive(60000);

After this all messages produced by this MessageProducer will have specified expiration time.

Also you can specify expiration tyme for concrete message during it's sending:

producer.send(message, DeliveryMode.NON_PERSISTENT, 3, 10000);

where 10000 means 10 seconds

Upvotes: 2

Love Hasija
Love Hasija

Reputation: 2568

  1. Yes, it will always remain in the queue, until it is consumed or it is removed from the queue manually or forcefully. And that's what about the durability property of JMS, and that's why it is preferred over RPC.

  2. About the receive method, it is a synchronous method and will block the thread until it receives a message to be consumed.

  3. About the Message Listener implementation, it follows the pull based model. Message broker keeps on querying the JMS server after some time, to see if there is a message to be consumed.

  4. Choosing from Option 3 and Option 4 depends on the requirements, blocking the thread has its own downside and will not let anything go furhter, and polling has its own downside, specially if the Jms server is running as a standalone server on a remote machine, and the broker has to use RMI to query for messages after some time.

UPDATE :: If you look at the enterprise integration Request/Reply patterns EIP, they have explained that because the messaging uses an asynchronous process, and hence there is no acknowledgment from the other end. If you want to send an acknowledgment back to the sender about the message, you can use msg.setJMSReplyTo which uses the acknowledgment message Correlation id to match with the sender message id to sync the request response.

Coming to temporary queue, it offers the benefit of creating the queues at runtime, bound to the given connection, rather than statically defining the queues at the deployment time, and the advantage is that it gives the lightweight alternative and helps in scaling the system to a much extent.

Upvotes: 2

Related Questions