为了说明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了。并发