ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Developing a Simple JMS Example
Pages: 1, 2, 3, 4

The Chat Application

Internet chat provides an interesting application for learning about the JMS pub/sub messaging model. Used mostly for entertainment, web-based chat applications can be found on thousands of web sites. In a chat application, people join virtual chat rooms where they can "chat" with a group of other people.



To illustrate how JMS works, we will use the JMS pub/sub API to build a simple chat application. The requirements of Internet chat map neatly onto the publish-and-subscribe messaging model. In this model, a producer can send a message to many consumers by delivering the message to a single topic. A message producer is also called a publisher and a message consumer is also called a subscriber. In reality, using JMS for a chat application would be overkill, since chat systems don't require enterprise quality service.

The following source code is a JMS-based chat client. Every participant in a chat session uses this Chat program to join a specific chat room (topic), and deliver and receive messages to and from that room:

package chap2.chat;

import javax.jms.*;
import javax.naming.*;
import java.io.*;
import java.io.InputStreamReader;
import java.util.Properties;

public class Chat implements javax.jms.MessageListener{
    private TopicSession pubSession;
    private TopicSession subSession;
    private TopicPublisher publisher;
    private TopicConnection connection;
    private String username;

    /* Constructor. Establish JMS publisher and subscriber */
    public Chat(String topicName, String username, String password)
    throws Exception {
        // Obtain a JNDI connection
        Properties env = new Properties( );
        // ... specify the JNDI properties specific to the vendor

        InitialContext jndi = new InitialContext(env);

        // Look up a JMS connection factory
        TopicConnectionFactory conFactory =
        (TopicConnectionFactory)jndi.lookup("TopicConnectionFactory");

        // Create a JMS connection
        TopicConnection connection =
        conFactory.createTopicConnection(username,password);

        // Create two JMS session objects
        TopicSession pubSession =
        connection.createTopicSession(false,
                                      Session.AUTO_ACKNOWLEDGE);
        TopicSession subSession =
        connection.createTopicSession(false,
                                      Session.AUTO_ACKNOWLEDGE);

        // Look up a JMS topic
        Topic chatTopic = (Topic)jndi.lookup(topicName);

        // Create a JMS publisher and subscriber
        TopicPublisher publisher = 
            pubSession.createPublisher(chatTopic);
        TopicSubscriber subscriber = 
            subSession.createSubscriber(chatTopic);

        // Set a JMS message listener
        subscriber.setMessageListener(this);

        // Intialize the Chat application
        set(connection, pubSession, subSession, publisher, username);

        // Start the JMS connection; allows messages to be delivered
        connection.start( );

    }
    /* Initialize the instance variables */
    public void set(TopicConnection con, TopicSession pubSess,
                    TopicSession subSess, TopicPublisher pub, 
                    String username) {
        this.connection = con;
        this.pubSession = pubSess;
        this.subSession = subSess;
        this.publisher = pub;
        this.username = username;
    }
    /* Receive message from topic subscriber */
    public void onMessage(Message message) {
        try {
            TextMessage textMessage = (TextMessage) message;
            String text = textMessage.getText( );
            System.out.println(text);
        } catch (JMSException jmse){ jmse.printStackTrace( ); }
    }
    /* Create and send message using topic publisher */
    protected void writeMessage(String text) throws JMSException {
        TextMessage message = pubSession.createTextMessage( );
        message.setText(username+" : "+text);
        publisher.publish(message);
    }
    /* Close the JMS connection */
    public void close( ) throws JMSException {
        connection.close( );
    }
    /* Run the Chat client */
    public static void main(String [] args){
        try{
            if (args.length!=3)
                System.out.println("Topic or username missing");

            // args[0]=topicName; args[1]=username; args[2]=password
            Chat chat = new Chat(args[0],args[1],args[2]);

            // Read from command line
            BufferedReader commandLine = new 
              java.io.BufferedReader(new InputStreamReader(System.in));

            // Loop until the word "exit" is typed
            while(true){
                String s = commandLine.readLine( );
                if (s.equalsIgnoreCase("exit")){
                    chat.close( ); // close down connection
                    System.exit(0);// exit program
                } else 
                    chat.writeMessage(s);
            }
        } catch (Exception e){ e.printStackTrace( ); }
    }
}

Getting Started with the Chat Example

To put this client to use, compile it like any other Java program. Then start your JMS server, setting up whatever topics, usernames, and passwords you want. Configuration of a JMS server is vendor-dependent, and won't be discussed here.

The Chat class includes a main( ) method so that it can be run as a standalone Java application. It's executed from the command line as follows:

java chap2.chat.Chat topic username password

The topic is the destination that we want to publish-and-subscribe to; username and password make up the authentication information for the client. Run at least two chat clients in separate command windows and try typing into one; you should see the text you type displayed by the other client.

Before examining the source code in detail, a quick explanation will be helpful. The chat client creates a JMS publisher and subscriber for a specific topic. The topic represents the chat room. The JMS server registers all the JMS clients that want to publish or subscribe to a specific topic. When text is entered at the command line of one of the chat clients, it is published to the messaging server. The messaging server identifies the topic associated with the publisher and delivers the message to all the JMS clients that have subscribed to that topic. As Figure 2-1 illustrates, messages published by any one of the JMS clients are delivered to all the JMS subscribers for that topic.

Diagram of the chat application.
Figure 2-1. The Chat application.

Examining the Source Code

Running the Chat example in a couple of command windows demonstrates what the Chat application does. The rest of this chapter examines the source code for the Chat application so that you can see how the Chat application works.

Bootstrapping the JMS client

The main( ) method bootstraps the chat client and provides a command-line interface. Once an instance of the Chat class is created, the main( ) method spends the rest of its time reading text typed at the command line and passing it to the Chat instance using the instance's writeMessage( ) method.

The Chat instance connects to the topic and receives and delivers messages. The Chat instance starts its life in the constructor, which does all the work to connect to the topic and set up the TopicPublisher and TopicSubscribers for delivering and receiving messages.

Pages: 1, 2, 3, 4

Next Pagearrow