Shared subscriptions in JMS

The IBM® IoT MessageSight JMS client provides support for shared subscriptions as an extension of the JMS 1.1 specification. JMS applications that use this extension to the JMS 1.1 specification can be compiled and run only with IBM IoT MessageSight JMS client implementations. You can use the client to configure durable and non-durable topic subscriptions to be shared. In a non-shared subscription, each consumer to a particular topic receives a copy of all of the messages that are published to that topic string. In a shared subscription, each message is delivered to only one of the consumers for that subscription. This is similar to message sharing on a multi-consumer queue.

Shared subscriptions can be bound to a client ID, or can exist within a global namespace. If a client ID is specified for a connection that is used to create or join a shared subscription, then the subscription is bound to only that client ID. In this case, the client ID specifies the namespace for the subscription name. If no client ID is specified for a connection that is used to create or join a shared subscription, then the global namespace is used. By using a global namespace, it is possible to share a subscription between multiple connections. This configuration can be used, for example, to allow load balancing of a message-driven bean application that runs on an application server cluster.

To create and join a shared subscription in JMS, you can use an extended set of methods that match the JMS 2.0 methods of Session. These methods are added in an interface ImaSubscription. The Session object that is returned by createSession() within IBM IoT MessageSight implements the ImaSubscription interface.
MessageConsumer consumer;
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
consumer = ((ImaSubscription)session).createDurableConsumer(topic, subName);
consumer = ((ImaSubscription)session).createSharedConsumer(topic, subName, selector);
consumer = ((ImaSubscription)session).createSharedDurableConsumer(topic, subName, selector);

Creating JMS shared subscriptions, examples of code

The following code examples show the configuration required to create JMS shared subscriptions.
Note: All shared subscriptions require a correctly configured topic messaging policy. Global-shared durable subscriptions also require a correctly configured subscription messaging policy.
Create a global-shared non-durable subscription
ConnectionFactory connectionFactory;
Connection connection;
Session session;
MessageConsumer consumer;
Topic topic;
String sharedSubName;
String selector = null; /* For this example, there is no selector for this subscription. */
.
.
.
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
topic = session.createTopic("theTopic");
consumer = ((ImaSubscription)session).createSharedConsumer(topic, sharedSubName, selector);
Create a private-shared durable subscription
ConnectionFactory connectionFactory;
Connection connection;
Session session;
MessageConsumer consumer;
Topic topic;
String sharedSubName;
String selector = null; /* For this example, there is no selector for this subscription. */
.
.
.
connection = connectionFactory.createConnection();

/* Setting the client ID makes shared subscriptions for this connection private shared subscriptions.
 * Only consumers in this connection can access the shared subscriptions created for this connection.
 */
connection.setClientID("myClient"); 
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
topic = session.createTopic("sharedTopic");
consumer = ((ImaSubscription)session).createSharedConsumer(topic, sharedSubName, selector);
Create a global-shared durable subscription
Note: The correct subscription messaging policy and topic messaging policy must be configured in IBM IoT MessageSight.
ConnectionFactory connectionFactory;
Connection connection;
Session session;
MessageConsumer consumer;
Topic topic;
String sharedDurableSubName;
String selector = null; /* For this example, there is no selector for this subscription. */
.
.
.
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
topic = session.createTopic("theTopic");
consumer = ((ImaSubscription)session).createSharedDurableConsumer(topic, sharedDurableSubName, selector);
Create a private-shared durable subscription
ConnectionFactory connectionFactory;
Connection connection;
Session session;
MessageConsumer consumer;
Topic topic;
String sharedDurableSubName;
String selector = null; /* For this example, there is no selector for this subscription. */
.
.
.
connection = connectionFactory.createConnection();

/* Setting the client ID makes shared subscriptions for this connection private shared subscriptions.
 * Only consumers in this connection can access the shared subscriptions created for this connection.
 */
connection.setClientID("myClient"); 
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
topic = session.createTopic("sharedTopic");
consumer = ((ImaSubscription)session).createSharedDurableConsumer(topic, sharedDurableSubName, selector);

JMS clients end their use of a durable subscription by using the JMS Session.unsubscribe method. This action permanently ends their use of the subscription and deletes it if there are no active subscribers. If there are active subscribers, this action fails with an exception; implement appropriate exception handling for this case.

JMS clients end their use of a non-durable subscription by using the JMS Session.unsubscribe method or by closing the consumers.