爲了說明JMS是如何工做的,咱們將使用JMS的pub/sub API來構建一個簡單的聊天應用程序。下面是一個基於JMS的聊天客戶端的完整源代碼清單。在一個聊天會話中,每一個聊天參與者都使用這個Chat程序,加入一個特定的聊天室(主題)之中,並向該聊天室傳送消息,以及從該聊天室中接收消息。如例:java
package ch01; import java.io.BufferedReader; import java.io.InputStreamReader; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.Session; import javax.jms.TextMessage; import javax.jms.Topic; import javax.jms.TopicConnection; import javax.jms.TopicConnectionFactory; import javax.jms.TopicPublisher; import javax.jms.TopicSession; import javax.jms.TopicSubscriber; import javax.naming.InitialContext; /** * 基於JMS的聊天應用程序 * @author fuhd */ public class Chat implements MessageListener { private TopicSession pubSession; private TopicPublisher publisher; private TopicConnection connection; private String userName; //用於初始化Chat的構造函數 public Chat(String topicFactory,String topicName,String userName) throws Exception{ //使用jndi.properties文件得到一個JNDI鏈接 InitialContext ctx = new InitialContext(); //查找一個JMS鏈接工廠並建立鏈接 TopicConnectionFactory conFactory = (TopicConnectionFactory)ctx. lookup(topicFactory); TopicConnection connection = conFactory.createTopicConnection(); //建立兩個JMS會話對象 TopicSession pubSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); TopicSession subSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); //查找一個JMS主題 Topic chatTopic = (Topic)ctx.lookup(topicName); //建立一個JMS發佈者和訂閱者。createSubscriber中附加的參數是一個 //消息選擇器(null)和noLocal標記的一個false值,它代表這個發佈者生 //產的消息也要被它本身所消費 TopicPublisher publisher = pubSession.createPublisher(chatTopic); TopicSubscriber subscriber = subSession.createSubscriber(chatTopic, null, false); //設置一個JMS消息偵聽器 subscriber.setMessageListener(this); //初始化Chat應用程序 this.connection = connection; this.pubSession = pubSession; this.publisher = publisher; this.userName = userName; //啓動JMS鏈接,容許傳遞消息 connection.start(); } //接收自TopicSubscriber的消息*/ @Override public void onMessage(Message message) { try { TextMessage textMessage = (TextMessage)message; System.out.println(textMessage.getText()); } catch (JMSException e) { e.printStackTrace(); } } //使用發佈者建立併發送消息 protected void writeMessage(String text) throws JMSException{ TextMessage message = pubSession.createTextMessage(); message.setText(userName + ": " + text); publisher.publish(message); } //關閉JMS鏈接 public void close() throws JMSException{ connection.close(); } public static void main(String[] args) { try { Chat chat = new Chat("TopicCF","topic1","fuhd"); //從命令行讀取 BufferedReader commandLine = new BufferedReader( new InputStreamReader(System.in)); //循環,直到鍵入「exit」爲止 while(true){ String s = commandLine.readLine(); if(s.equalsIgnoreCase("exit")){ chat.close(); System.exit(0); }else{ chat.writeMessage(s); } } } catch (Exception e) { e.printStackTrace(); } } }
請注意:使用createSubscriber()方法建立接收者時,它採用3個參數而不單單是一個參數。這樣就能夠設置noLocal標記(第3個參數),若是值爲true,本身不接收本身所發的消息,若是值爲false,本身也接收本身發的消息。第2個參數用於一個消息選擇器,因爲並不對主題作任何過濾,這個值就被設置爲null了。併發