import javax.jms.*; import javax.naming.*; import java.awt.*; import java.awt.event.*; import java.io.*; /** * JMSChatThread implements the thread which communicates using the JMS API. * It supports two modes of operation, one which sends messages to a topic * (publishes), and one which receives messages from a topic (subscribes). * The mode of operation is specified when the thread is created. */ public class JMSChatThread extends Thread { // JNDI and JMS objects private Context jndiContext = null; private TopicConnectionFactory topicConnectionFactory = null; private TopicConnection topicConnection = null; private TopicSession topicSession = null; private Topic topic = null; private TextMessage message = null; private String input = null; // The two modes of operation static final int SENDER = 0; static final int RECEIVER = 1; // Which mode this thread should run in int mode; // The topic to use static String topicName = null; // The nickname of the sender static String userName = null; private ChatData controlData; /** * Class constructor. * * @param mode mode of operation * @param controlData control flags and data * @param user user name from login panel * @param topic topic name from login panel */ public JMSChatThread(int mode, ChatData controlData, String user, String topic) { this.mode = mode; this.controlData = controlData; this.userName = user; this.topicName = topic; } /** * The entry point for the thread. */ public void run() { // Mode of operation determines if sender or receiver switch(mode) { case SENDER: sendRequests(); // Publisher break; case RECEIVER: listen(); // Subscriber break; default: System.out.println("Invalid value for mode: " + mode); } } /** * Thread exit processing. This closes the JMS connection. */ public void tidyUp() { if (topicConnection != null) { try { topicConnection.close(); } catch (JMSException e) { System.out.println("Exception occurred: " + e.toString()); } finally { topicConnection = null; } } } /** * Sender (publisher) thread. * The sender thread establishes the JMS connection and then * loops publishing messages to the JMS chat topic. */ void sendRequests() { TopicPublisher topicPublisher = null; /* * Create a JNDI InitialContext object if none exists yet. */ try { jndiContext = new InitialContext(); } catch (NamingException e) { System.out.println("Could not create JNDI " + "context: " + e.toString()); System.exit(1); } /* * Look up connection factory and topic. If either does * not exist, exit. */ try { topicConnectionFactory = (TopicConnectionFactory) jndiContext.lookup("TopicConnectionFactory"); topic = (Topic) jndiContext.lookup(topicName); } catch (NamingException e) { System.out.println("JNDI lookup failed: " + e.toString()); System.exit(1); } /* * Create connection. * Create session from connection; false means session is * not transacted. * Create publisher. * Send text messages until error or interrupted. * Close connection, if necessary. */ try { topicConnection = topicConnectionFactory.createTopicConnection(); topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); topicPublisher = topicSession.createPublisher(topic); message = topicSession.createTextMessage(); topicPublisher.publish(message); topicConnection.start(); // Let the client know connection established controlData.senderConnected(); // Send messages while (true) { input = controlData.retrieveOutbound(); if (input != null) { message.setText(userName + ": " + input); topicPublisher.publish(message); } } } catch (Exception e) { // If not time to exit then report an error if (!controlData.timeToExit()) { System.out.println("Exception occurred: " + e.toString()); } } finally { if (topicConnection != null) { try { topicConnection.close(); } catch (JMSException e) { System.out.println("Exception occurred: " + e.toString()); } } } } /** * Receiver (subscriber) thread. * The receiver thread establishes the JMS connection and then * loops receiving messages from the JMS chat topic. */ void listen() { TopicSubscriber topicSubscriber = null; Message msg = null; /* * Create a JNDI InitialContext object if none exists yet. */ try { jndiContext = new InitialContext(); } catch (NamingException e) { System.out.println("Could not create JNDI " + "context: " + e.toString()); System.exit(1); } /* * Look up connection factory and topic. If either does * not exist, exit. */ try { topicConnectionFactory = (TopicConnectionFactory) jndiContext.lookup("TopicConnectionFactory"); topic = (Topic) jndiContext.lookup(topicName); } catch (NamingException e) { System.out.println("JNDI lookup failed: " + e.toString()); System.exit(1); } /* * Create connection. * Create session from connection; false means session is * not transacted. * Create subscriber. * Receive text messages from topic until error or exit. * Close connection, if necessary. */ try { topicConnection = topicConnectionFactory.createTopicConnection(); topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); topicSubscriber = topicSession.createSubscriber(topic); topicConnection.start(); // Let the client know connection established controlData.receiverConnected(); // Receive messages while (true) { msg = topicSubscriber.receive(); if (msg instanceof TextMessage) { message = (TextMessage) msg; input = message.getText(); if (input != null) { controlData.storeInbound(input); } } } } catch (Exception e) { // If not time to exit then report an error if (!controlData.timeToExit()) { System.out.println("Exception occurred: " + e.toString()); } } finally { if ((!controlData.timeToExit()) && (topicConnection != null)) { try { topicConnection.close(); } catch (JMSException e) { System.out.println("Exception occurred: " + e.toString()); } } } } }