上节简单描述了一下JMS的概念,这节来写个小demo。这样可以比较直观的看到JMS通信的过程。
前期回顾:04_Java通信_JMS概念
在开发这个demo前,首先要下载ActiveMQ来作为消息服务器。
Demo实现功能
这是我们要实现的一个发布/订阅模型的demo
A发送消息到消息服务器ActiveMQ,然后ActiveMQ将消息发给订阅这个Topic的客户端:A和B
开发流程:
1.要开发一个jms demo首先要下载某厂商的JMS的实现
2.下载ActiveMQ,这是Apache的一个开源MQ系统
下载地址:http://activemq.apache.org/download.html
下载历史版本:http://activemq.apache.org/download-archives.html
3.下载后直接解压
我们开发一个demo直接可以使用这个activemq-all-5.2.0.jar这个jar包
4.还需要jms的jar包:
如果使用Maven,可以使用下面的依赖:
<dependency> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> <version>1.1</version> </dependency>
5.开发一个简单的聊天demo,就想上面那张聊天图一样
package com.jms.test; import java.io.BufferedReader; import java.io.InputStreamReader; import javax.jms.JMSException; import javax.jms.Message; 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.Context; import javax.naming.InitialContext; public class Chat implements javax.jms.MessageListener { private TopicSession pubSession; private TopicPublisher publisher; private TopicConnection conntection; private String username; public Chat(String topicFactory,String topicName,String username) throws Exception{ // System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory"); // System.setProperty(Context.PROVIDER_URL, "tcp://localhost:61616"); // //使用JNDI获得ConnectionFactory InitialContext ctx = new InitialContext(); TopicConnectionFactory conFactory = (TopicConnectionFactory)ctx.lookup(topicFactory); //通过ConnectionFactory得到Connection TopicConnection connection = conFactory.createTopicConnection(); //得到session TopicSession pubSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); TopicSession subSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); //使用JNDI查找主题Topic Topic chatTopic = (Topic)ctx.lookup(topicName); //通过session和主题Topic获得发布者,订阅者 TopicPublisher publisher = pubSession.createPublisher(chatTopic); TopicSubscriber subscriber = subSession.createSubscriber(chatTopic); subscriber.setMessageListener(this); this.conntection = connection; this.pubSession = pubSession; this.publisher = publisher; this.username = username; conntection.start(); } @Override public void onMessage(Message m) { try { // m.set TextMessage tm = (TextMessage)m; System.out.println(tm.getText()); } catch (JMSException e) { e.printStackTrace(); } } protected void writeMessage(String text) throws Exception{ TextMessage message = pubSession.createTextMessage(); message.setText(username+": "+text); //消息发送者,发送消息 publisher.publish(message); } public void close() throws Exception{ conntection.close(); } public static void main(String[] args) throws Exception { Chat chat = new Chat("TopicCF","topic1","hh"); BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); while(true){ String s = commandLine.readLine(); if(s.equalsIgnoreCase("exit")){ chat.close(); System.exit(0); }else{ chat.writeMessage(s); } } } }
6.配置文件:
java.naming.factory.initial =org.apache.activemq.jndi.ActiveMQInitialContextFactory java.naming.provider.url =tcp://localhost:61616 java.naming.security.principal =system java.naming.security.credentials =manager connectionFactoryNames =TopicCF topic.topic1 =jms.topic1
7.客户端B:
package com.jms.test; import java.io.BufferedReader; import java.io.InputStreamReader; public class ChatA { public static void main(String[] args) throws Exception { Chat chat = new Chat("TopicCF","topic1","cc"); BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); while(true){ String s = commandLine.readLine(); if(s.equalsIgnoreCase("exit")){ chat.close(); System.exit(0); }else{ chat.writeMessage(s); } } } }
8.如何运行代码:
启动消息服务器ActiveMQ
进入ActiveMQ的bin目录
双击运行:activemq.bat
查看是否启动成功:cmd-->netstat -na|find "61616"
出现:
则启动成功。还可以登陆
admin:http://127.0.0.1:8161/admin/
demo:http://127.0.0.1:8161/demo/
查看。
将配置文件jndi.properties放在classes的根目录。
项目目录结构:
代码难点分析:
1.在前面已经介绍过JNDI。我们可以通过JNDI来获取通信对象。
JMS客户端使用一个目录服务(JNDI)来访问ConnectionFactory和Destination(主题和队列)对象。也就是说这两个对象JMS API无法获得。在这一点上,它和连接,会话,生产者,消费者及消息不同。连接,会话,生产者,消费者及消息都是JMS API内部使用工厂模式生产的。JNDI为了获得ConnectionFactory和Destination对象提供了一种方便、位置透明、可配置并且可移植的机制,这些对象也称为JMS受管对象,因为它是由系统管理员建立和配置的
2.线程和会话
在程序中创建了两个topicSession:pubSession,subSession。
为什么要创建两个呢,因为JMS规定一个session不能同时在一个以上的线程中运行。
这个例子中有两个线程:
运行writeMessage的主线程(线程所有者:chat应用程序)
运行onMessage的处理线程(线程所有者是JMS提供者所有,即:ActionMQ)
相关推荐
java消息系统 JMS 学习代码 例子 jar
MQ软件提供一个JAVA软件包,里面有JMS类库,和一套MQ的类库。不熟悉MQI编程方法的程序员可以用JMS,比较熟悉MQI编程方法的程序则可以用MQ类库来编程。下面的小程序是使用Java实现从队列管理器QM_SERVER中的队列INITQ...
用jms 向webshpere mq里发送消息
文件包含: 13个不同固件 两个固件升级工具 其中一个是量产工具可以修改休眠时间和盒子信息 TRIM检查工具 有几个固件版本为全网首发,别人没有的资源 固件列表: JMS578_00.01.00.05 ...JMS578_254.02.03.09_NoUAS
Jmicron JMS583 Datasheet USB 3.1 Gen 2 to PCIe Gen3x2 Bridge
jms 简单的案例,用的activemq,使用jms前请先启动activemq服务器
使用WebSphere_MQ_Java和JMS_API_对消息进行分组.
JMS demo 及 资料 jms入门 JMS入门级的蹩脚篇.ppt
TIBCO Rendezvous — 技术介绍 TIBCO Rendezvous(或称为TIBCO RV)产品是一种中间件,它具有发布/订阅(Publish/Subscribe)、基于主题寻址(Subject-Based Addressing) 和自定义数据信息(Self-Describing Data ...
activeMQ DEMO show how to use it
esper和jms做的小demo,模拟温度控制
W25X20_20210512_4011_WD_MyBook_JMS578_Standard.BIN
J2SE应用编程JMS设计代码JMS Design J2SE application programming code
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的...
一个完整的flex与java整合通信实例源码 采用了blazeds技术与java通信
实现MessageConverter接口来转换JMS对象与java对象.. 其实在使用MessageListenerAdapter时,Spring默认为我们提供了SimpleMessageConverter转换器.. 事务(无代码): 在Spring整合JMS的应用中,如果我们要进行本地...
JMS583也是大家找了很久的主控,因为有墙所以下载不了,市面上硬盘盒基本是这个主控,为防止万一建议自己再检测一下先。因为版本问题,大家估计都是2.0.5和我的蓝硕SSD硬盘盒一样,我就是用这个固件解决的掉速问题。
JMicron JMS578 USB/SATA bridge JMS578介绍手册JMS578_Product+Brief.pdf JMS578固件(支持Android系统/linux系统) JMS578 windows的烧录工具和JMS578FwUpdate JMS578-Hardkenel-Release-v173.01.00.02-20190306....
Spring对JMS提供了很好的支持,可以通过JmsTemplate来方便地实现消息服务。本例通过activeMQ服务器模拟了消息的发送与接收。需要注意的是,activeMQ的运行依赖jdk的环境,而且对jdk的版本也有要求,我用的是jdk1.6+...
WSAD环境下JMS异步通信全攻略。有截图说明