JMS eases the timing dependency of the pub/sub model by permitting the creation of durable subscriptions, which may receive messages while subscribers are not active. In addition, the use of durable subscriptions provides the flexibility and reliability achieved through the use of queues, while still permitting messages to be sent to many recipients.
Topic Subscriber topic Subscriber = topicSession.createDurableSubscriber(topic, subscriptionName);
A Connection object represents a connection to the messaging system for either messaging model. The server and client-side objects required to manage the state of the JMS connection are created by the connection. Connections are created by a Connection Factory and located via a JNDI lookup.
//Getting a QueueConnectionFactory for P2P QueueConnectionFactory = queueConnectionFactory( ); Context messaging = new InitialContext( ); QueueConnectionFactory = (QueueConnectionFactory) Messaging.lookup(“QueueConnectionFactory”); //Getting a TopicConnectionFactory for pub/sub TopicConnectonFactory topicConnectionFactory; Context messaging = new InitialContext(); topicConnectionFactory = (TopicConnectionFactory) messaging.lookup(“TopicConnectionFactory”);
Note: The code for the Point-to-Point and the PublishSubscribe is very similar.
Message acknowledgment is handled automatically by commit and recovery if the session is marked as transactional. If a session is not transactional, you have three options for message acknowledgment.
AUTO_ACKNOWLEDGEThe session will automatically acknowledge receipt of a message.
CLIENT_ACKNOWLEDGEA client will acknowledges a message by calling the message's acknowledge method.
DUPS_OK_ACKNOWLEDGEThis option instructs the session to lazily acknowledge message delivery. It is conceivable this will result in the delivery of some duplicate messages should the provider fail. This mode of acknowledgment should only be used if the consumer can tolerate the potential for duplicate messages.
queueSession = //P2P
topicSession = //Pub-Sub
NOTE: In this example a session object is created from the connection; false indicates the session is non-transactional, and the session will automatically acknowledge receipt of a message.
JMS currently has two modes of delivery for messages. A message
NON_PERSISTENT is delivered at most once, while
a message marked as
PERSISTENT will use a store and
forward mechanism and should be delivered once and only once. If a
JMS service is offline for whatever reason, the persisted message is
not lost but, rather, will be delivered when the service is brought
back online. The default message delivery mode is nonpersistent.
Although using nonpersistent messages may reduce overhead and storage
needs, this delivery mode should only be used if you can afford not to
receive all messages.
Although the JMS specification doesn't require JMS vendors to implement priority routing of messages, it does, however, require a best effort to deliver expedited messages ahead of normal messages. JMS defines priority routing levels from 0 to 9; 0 is the lowest priority and 9 the most expedited. More specifically, 0 to 4 are varying degrees of normal priority and 5 to 9 are varying degrees of expedited priority. For example,
topicPublisher.publish //Pub-Sub (message, DeliveryMode.PERSISTENT, 8, 10000);
queueSender.send//P2P (message, DeliveryMode.PERSISTENT, 8, 10000);
This code snippet, for both messaging models, reflects the delivery mode as being persistent, the priority routing as expedited, and time to live is 10000 (measured in milliseconds). If the time to live were set to zero this would indicate the message would never expire. Time to live proves useful when messages need to be expired or otherwise invalidated.
JMS defines five different message body formats, also called message types, which allow you to send and receive data in several different forms, providing some level of compatibility with existing messaging formats.
StreamMessage-- a stream of Java primitive values
MapMessage-- a set of name-value pairs
TextMessage-- a String object
ObjectMessage-- a serialized Java object
BytesMessage-- a stream of uninterpreted bytes
The JMS API provides methods for creating messages of each type and for setting the payload. For example, to create and send a TextMessage to a queue, you might use the following statement:
TextMessage message = queueSession.createTextMessage();
message.setText(textMsg); // textMsg is a String