??Java 消息服務(JMS)可以幫助我們減少應用程序間的耦合,而同時又允許應用程序間的通信以及使用對方的資源。JMS 一般都包含至少三個組成部分:兩個JMS 客戶和一個 JMS 服務器。兩個客戶通過 JMS 服務器相互通信。JMS 客戶是使用 JMS API發送和接收消息的常規應用程序。
????JMS 服務器可以是任何實現 JMS 規范的應用程序。一些 JMS 服務器是更大的應用程序的一部分;還有一些是專門負責 JMS 任務的應用程序。有很多第三方商業資源和一些開放源代碼資源的 JMS 服務器可供選擇使用。應用程序使用 JMS 相互通信有兩個方法可以選用:JMS 主題和 JMS 隊列。主題和隊列只在很少一些地方有區別,其中最明顯的區別是它們發送消息的方式不同。
????JMS 主題從一個 JMS 客戶接收消息然后將這些消息分發給所有注冊為主題監聽者的 JMS 客戶。相反,JMS 隊列只將消息分發給一個客戶,不管有多少客戶注冊為隊列監聽者。如果兩個或者多個客戶注冊到一個隊列,同時一個消息存儲在隊列中,那么只有一個客戶能接收到這個消息。
????JMS 規范沒有規定哪個客戶將接收這個消息。不管你是使用 JMS 主題還是 JMS 隊列,消息中所要傳遞的數據的類型都在于你自己。一些程序員通過他們的消息系統發送商業對象,而其它程序員以文本格式發送 XML 消息從而進一步地減少耦合。如果你以前沒有用過 JMS,那么可能是因為你還沒有一個使用它的原因。如果你以前編寫過你自己的消息系統,那么很可能你將從 JMS API 中受益。
????JRun服務器已經提供了對JMS的支持,且內置了JMS服務,以JRun4.0為例,主要配置文件有{JRun-Home}/server/servers/{server-name}/SERVER-INF/jrun-jms.xml和jrun-resources.xml,查看jrun-jms.xml文件可以知道jrun對于JMS Message的持久化有兩種方式,一個是文件方式,一個是數據庫方式,默認是文件來保存JMS Message:
<persistence-manager>???????????
?<active-adapter-type>file</active-adapter-type>???????????
?<persistence-adapter>?????????????????
??<adapter-type>file</adapter-type>???????????
?</persistence-adapter>???????????
?<persistence-adapter>?????????????????
??<adapter-type>rdbm</adapter-type>???????????
?</persistence-adapter>?????
</persistence-manager>
?這里需要注意的就是把<client-jndi>的注釋去掉,并修改provider-url為服務器實際地址,此處為例為192.168.2.240:2908,注意2908是此Server提供的JNDI服務端口,因為JMS服務是綁定到server的JNDI服務上的,客戶端需要查詢JNDI。再修改run-resources.xml添加測試的JMS隊列(也可以通過JRun控制臺添加)
?
<jms-destination>????????????????
????<jndi-name>jms/queue/testQueue</jndi-name>????????????????????
????<destination-name>testQueue</destination-name>
????<destination-type>javax.jms.Queue</destination-type>????
</jms-destination>再添加QueueConnectionFactory
<jms-connection-factory>
????<factory-name>QueueConnectionFactory</factory-name>
????<jndi-name>jms/jndi-QueueConnectionFactory</jndi-name>
????<type>javax.jms.QueueConnectionFactory</type>
????<transport>RMI</transport>
????<username>guest</username>
????<password>guest</password>
</jms-connection-factory>?
上面transport是指傳輸消息所用的協議,RMI:java遠程方法調用,TCP:TCP/IP協議,Intra-VM:只在本虛擬機傳輸消息,用戶名/密碼是服務驗證客戶端調用時使用。服務器端JMS的設置基本完成了,還需要設置jrun的安全策略。
修改{JRun-Home}/server/security.properties,有兩項jrun.subnet.restriction:子網掩碼,jrun.trusted.hosts:信任主機的IP,否則遠程調用可能會被拒絕。再到{JRun-Home}/bin下修改jvm.config,添加java虛擬機啟動參數-Djava.rmi.server.hostname=192.168.2.240,其中192.168.2.240為主機的實際IP,不要寫localhost,否則RMI的遠程調用會被拒絕。也可以寫一個新配置文件new-server.conf,啟動時用命令jrun –config new-server.conf –start XXX指定配置文件。服務器端的設置完成。當然如果客戶端程序也在此JRun中運行,可以忽略這些參數的修改和設置。
????客戶端的代碼基本與調用其他JMS服務類似。注意要取得{JRun-Home}/lib/jrun.jar并放入到客戶端環境的classpath中,代碼示例
?

public?class?JmsQueueTest...{????????
????private?Context?context?=?null;????????
????private?QueueConnection?connection??=?null;????????
????private?QueueSession?session?=?null;????????
????private?Queue?queue?=?null;????????
????private?QueueSender?sender??=?null;????????
????private?String?connectionFactory;????????
????private?String?queueJndiName;????????

????public?void?setConnectionFactory(String?connectionFactory)...{
????????this.connectionFactory?=?connectionFactory;
????}????????

????public?void?setQueueJndiName(String?queueJndiName)...{
????????this.queueJndiName?=?queueJndiName;????????
????}????????

????/**?*//**?????????
????*?初始化JMS隊列?????????
????*?@param?ctxFactory?????????
????*?@param?url?????????
????*?@param?user?????????
????*?@param?pwd?????????
????*?@throws?Exception?????????
????*/????????

????public?void?init(String?ctxFactory,String?url,String?user,String?pwd)throws?Exception?...{
????????Properties?p?=?new?Properties();
????????p.put(Context.INITIAL_CONTEXT_FACTORY,ctxFactory);
????????p.put(Context.PROVIDER_URL,url);
????????p.put(Context.SECURITY_PRINCIPAL,user);
????????p.put(Context.SECURITY_CREDENTIALS,pwd);
????????context?=?new?InitialContext(p);
????????QueueConnectionFactory?factory?=?(QueueConnectionFactory)context.lookup(connectionFactory);
????????connection?=?factory.createQueueConnection();
????????queue?=?(Queue)context.lookup(queueJndiName);
????????session?=?connection.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
????????sender?=?session.createSender(queue);
????????connection.start();????????
????}????????

????/**?*//**?????????
????*?發送文本消息?????????
????*?@param?txt?????????
????*?@throws?Exception?????????
????*/????????

????public?void?send(String?txt)throws?Exception?...{
????????TextMessage?tmsg?=?session.createTextMessage();????????
????????tmsg.setText(txt);?sender.send(tmsg);????????
????}????????

????/**?*//**?????????
????*?查詢隊列中保存的消息?????????
????*?@throws?Exception?????????
????*/????????

????public?void?browser()throws?Exception...{
????????QueueBrowser?browser?=?session.createBrowser(queue);
????????Enumeration?enum?=?browser.getEnumeration();System.out.println("QueueBrowser");

????????while?(enum.hasMoreElements())...{????????
????????????System.out.println(enum.nextElement());
????????}
????????browser.close();????????
????}????????

????/**?*//**?????????
????*?接收消息?????????
????*?@throws?Exception?????????
????*/????????

????public?void?receive()throws?Exception...{
????????QueueReceiver?receiver?=?session.createReceiver(queue);

????????while(true)...{
????????????TextMessage?message?=?(TextMessage)receiver.receiveNoWait();????????
????????????if(message?==?null)break;????????
????????????System.out.println("receive?message:"?+?message.getText());
????????}
????????receiver.close();????????
????}????????

????public?void?close()throws?Exception...{
????????sender.close();
????????session.close();
????????connection.close();
????????context.close();????????
????}

????public?static?void?main(String[]?args)throws?Exception?...{
????????String?ctxFactory?=?"jrun.naming.JRunContextFactory";
????????String?url?=?"192.168.2.240:2908";
????????String?user?=?"guest";
????????String?pwd?=?"guest";
????????String?connectionFactoryJndi?=?"jms/jndi-QueueConnectionFactory";
????????String?queueJndi?=?"jms/queue/testQueue";
????????JmsQueueTest?test?=?new?JmsQueueTest();
????????test.setConnectionFactory(connectionFactoryJndi);
????????test.setQueueJndiName(queueJndi);
????????test.init(ctxFactory,url,user,pwd);
????????test.send("java共舞JMS消息");
????????test.browser();
????????test.receive();
????????test.close();????????
????}Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1151182