灵魂-放水

为学日益,为道日损。

BlogJava 首页 新随笔 联系 聚合 管理
  296 Posts :: 10 Stories :: 274 Comments :: 0 Trackbacks
  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

posted on 2006-09-08 14:29 放水老倌 阅读(308) 评论(0)  编辑  收藏 所属分类: J2EE

只有注册用户登录后才能发表评论。


网站导航: