Message Hub

The jWebSocket Message Hub for internal/external communication

The jWebSocket framework provides a generic JMS based component designed for components messaging. Suggested to be used in filters, plug-ins, script applications and other kind of solutions, it provides simple and useful methods to exchange messages.

Refreshing readers mind: The Java Message Service (JMS) API is a Java Message Oriented Middleware (MOM) API for sending messages between two or more clients. JMS is a part of the Java Platform, Enterprise Edition, and is defined by a specification developed under the Java Community Process as JSR 914. It is a messaging standard that allows application components based on the Java Enterprise Edition (Java EE) to create, send, receive, and read messages. It allows the communication between different components of a distributed application to be loosely coupled, reliable, and asynchronous. https://en.wikipedia.org/wiki/Java_Message_Service

The JMSManager class

Located in the jWebSocketCommon module, the JMSManager class has been designed for easy to use JMS, inspired on the STOMP JavaScript library: http://www.jmesnil.net/stomp-websocket/doc/.

System Instance configuration

The JMSManager system instance is required by the jWebSocket server, it is configured in the "conf/SystemPlugIn/system.xml" configuration file:
<!-- JMS Manager -->
<bean id="jmsManager" class="org.jwebsocket.util.JMSManager">
  <constructor-arg index="0" value="false"/>
  <constructor-arg index="1" ref="jmsConnection0"/>
  <constructor-arg index="2" value="topic://jwebsocket_messagehub"/>
</bean>
Where "jmsConnection0" bean is defined in "conf/Resources/bootstrap.xml" configuration file. As a system administrator or developer you may be able to change these settings according to your requirements and scenarios.
If your jWebSocket server runs as member of a jWebSocket cluster, the JMS connection is provided by the JMSEngine.

Accessing the JMSManager system instance from code

From any location on your jWebSocket app:
JMSManager lJMS = (JMSManager) JWebSocketBeanFactory.getInstance().getBean("jmsManager");
From token plug-ins and token filters:
JMSManager lJMS = getServer().getJMSManager();

Creating new JMSManager instances

If you require to create a new JMSManager instance for special requirements on your app, it is also very simple:

/**
 * Create new JMSManager instance
 * 
 * @param aUseTransaction Indicates if the internal JMS session will use transactions
 * @param aConn The JMS connection to use
 */
public JMSManager(boolean aUseTransaction, Connection aConn) {...}
/**
 * Create new JMSManager instance
 * 
 * @param aUseTransaction Indicates if the internal JMS session will use transactions
 * @param aConn The JMS connection to use
 * @param aDefaultDestination The default destination to send messages (default: "topic://jwebsocket_messagehub")
 */
public JMSManager(boolean aUseTransaction, Connection aConn, String aDefaultDestination) {…}

Sending messages

 

// building the message
MapMessage lMessage = lJMSManager.buildMessage("your app namespace", "message name");
lMessage.setStringProperty("var1", "Some string val");
lMessage.setBooleanProperty("var2", true);
// if you want to include the jWebSocket server node for clustering processing
lMessage.setStringProperty(Attributes.NODE_ID, JWebSocketConfig.getConfig().getNodeId());

// sending the message to default destination
lJMSManager.send(lMessage);

// sending to custom destination
lJMSManager.send("topic://a_topic_name", lMessage);
lJMSManager.send("queue://a_queue_name", lMessage);

Receiving messages

To process messages using the JMS technology, you require to subscribe with a message listener instance to a target destination.

// listening all messages in default destination
String lSubscriptionId = lJMSManager.subscribe(new MessageListener() {

  @Override
  public void onMessage(Message aMessage) {
    try {
      // message processing here
			
    } catch(Exception lEx){}
  }
});

// listening all messages in custom destination
String lSubscriptionId = lJMSManager.subscribe("topic://a_topic_name", new MessageListener() {

  @Override
  public void onMessage(Message aMessage) {
    try {
      // message processing here
			
    } catch(Exception lEx){}
  }
});

// listening messages in default destination from a target sender only
String lSubscriptionId = lJMSManager.subscribe(new MessageListener() {

  @Override
  public void onMessage(Message aMessage) {
    try {
      // message processing here
		
    } catch(Exception lEx){}
  }
}, "NS = 'target sender namespace'");
For more documentation about JMS message selectors see: http://docs.oracle.com/cd/E19798-01/821-1841/bncer/index.html

If you want to terminate a previous subscription just call the method “unsubscribe” passing the subscription identifier:

lJMSManager.unsubscribe(lSubscriptionId);

System events passing through the message hub

The jWebSocket system plug-in uses the message hub instance to broadcast the following system events notifications to interested local/cluster listeners.
  • connectorStarted: Passes the "connectorId:String" as parameter.
  • connectorStopped: Passes the "connectorId:String" as parameter.
  • logon: Passes the "connectorId:String" and "username:String" as parameters.
  • logoff: Passes the "connectorId:String" and "username:String" as parameters.
  • sessionStarted: Passes the "connectorId:String" as parameter.
  • sessionStopped: Passes "username:String", "uuid:String", "authenticated:Boolean", "authorities:String" parameters.

Example capturing a system event:

// listening "logon" system event
String lSubscriptionId = lJMSManager.subscribe(new MessageListener() {

  @Override
  public void onMessage(Message aMessage) {
    try {
      String lUsername = aMessage.getStringProperty("username");
    } catch(Exception lEx){}
  }
}, "NS = 'org.jwebsocket.plugins.system' AND msgType='logon'");

General considerations

 
  1. The JMSManager always expect an “started” JMS connection instance.
  2. If you decided to use transactions in your JMSManager instance, don't forget to call method “commit” to send queued messages:
  3. lJMSManager.commit();
  4. If you finished to work with your custom JMSManager instance (not system instance), call method “shutdown” to release unneeded resources:
  5. lJMSManager.shutdown();
  6. Sending the jWebSocket server node-id value is suggested if your plan is to notify clustered applications, then you can exclude the sender application from message processing.
  7. Using the JMSManager in scripting applications is also pretty simple: http://jwebsocket.org/documentation/Plug-Ins/Scripting-Plug-In/Developer-Guide/jms-integration

     

 
 

Copyright © 2013 Innotrade GmbH. All rights reserved.