- 浏览: 272148 次
- 性别:
- 来自: 北京
最新评论
-
gotosuzhou:
好的 谢谢分享
Spring 事务异常回滚 -
cd249745647:
哈哈
Spring MVC REST 例子 -
向日葵上的小蜜蜂:
代码都差不多贴出来了,为啥不直接提供下载呢
Spring MVC REST 例子 -
he3109006290:
我猜它应该有个算法,当出现长时间处理的情况的,它自动会启动另外 ...
netty 疑惑 -
yanghoho6:
很好, 学习了,
oracle基本的索引概念.doc
How should I implement request response with JMS?
The simplest solution is to use Camel as a Spring Remoting provider which allows you to hide all the JMS API from your business logic and letting Camel provide the request/response handling code for you.
However if you wish to write the JMS client code yourself, please read on how it works...
Using the JMS API to implement request-response
You might think at first that to implement request-response type operations in JMS that you should create a new consumer with a selector per request; or maybe create a new temporary queue per request.
Creating temporary destinations, consumers, producers and connections are all synchronous request-response operations with the broker and so should be avoided for processing each request as it results in lots of chat with the JMS broker.
The best way to implement request-response over JMS is to create a temporary queue and consumer per client on startup, set JMSReplyTo property on each message to the temporary queue and then use a correlationID on each message to correlate request messages to response messages. This avoids the overhead of creating and closing a consumer for each request (which is expensive). It also means you can share the same producer & consumer across many threads if you want (or pool them maybe).
The Lingo library is an implementation of Spring remoting using JMS. (Spring remoting is a kind of POJO based remoting where the remoting code is invisible to your business logic code).
It uses exactly this pattern; of using correlation IDs to correlate requests to responses. The server side just has to remember to put the inbound message's correlation ID on the response.
The actual class which does this is the MultiplexingRequestor . It may be just using Spring remoting with Lingo is the simplest way of implementing request response - or maybe you could just use Lingo's Requestor interface to keep the JMS semantics.
More details here
Client side
So the client side creates a consumer on a temporary queue as follows...
// client side Destination tempDest = session.createTemporaryQueue(); MessageConsumer responseConsumer = session.createConsumer(tempDest); ... // send a request.. message.setJMSReplyTo(tempDest) message.setJMSCorrelationID(myCorrelationID); producer.send(message);
Server side
public void onMessage(Message request) {
Message response = session.createMessage();
response.setJMSCorrelationID(request.getJMSCorrelationID())
producer.send(request.getJMSReplyTo(), response)
}
Full Examples
Server Side
import org.apache.activemq.broker.BrokerService; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class Server implements MessageListener { private static int ackMode; private static String messageQueueName; private static String messageBrokerUrl; private Session session; private boolean transacted = false; private MessageProducer replyProducer; private MessageProtocol messageProtocol; static { messageBrokerUrl = "tcp://localhost:61616"; messageQueueName = "client.messages"; ackMode = Session.AUTO_ACKNOWLEDGE; } public Server() { try { //This message broker is embedded BrokerService broker = new BrokerService(); broker.setPersistent(false); broker.setUseJmx(false); broker.addConnector(messageBrokerUrl); broker.start(); } catch (Exception e) { //Handle the exception appropriately } //Delegating the handling of messages to another class, instantiate it before setting up JMS so it //is ready to handle messages this.messageProtocol = new MessageProtocol(); this.setupMessageQueueConsumer(); } private void setupMessageQueueConsumer() { ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(messageBrokerUrl); Connection connection; try { connection = connectionFactory.createConnection(); connection.start(); this.session = connection.createSession(this.transacted, ackMode); Destination adminQueue = this.session.createQueue(messageQueueName); //Setup a message producer to respond to messages from clients, we will get the destination //to send to from the JMSReplyTo header field from a Message this.replyProducer = this.session.createProducer(null); this.replyProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); //Set up a consumer to consume messages off of the admin queue MessageConsumer consumer = this.session.createConsumer(adminQueue); consumer.setMessageListener(this); } catch (JMSException e) { //Handle the exception appropriately } } public void onMessage(Message message) { try { TextMessage response = this.session.createTextMessage(); if (message instanceof TextMessage) { TextMessage txtMsg = (TextMessage) message; String messageText = txtMsg.getText(); response.setText(this.messageProtocol.handleProtocolMessage(messageText)); } //Set the correlation ID from the received message to be the correlation id of the response message //this lets the client identify which message this is a response to if it has more than //one outstanding message to the server response.setJMSCorrelationID(message.getJMSCorrelationID()); //Send the response to the Destination specified by the JMSReplyTo field of the received message, //this is presumably a temporary queue created by the client this.replyProducer.send(message.getJMSReplyTo(), response); } catch (JMSException e) { //Handle the exception appropriately } } public static void main(String[] args) { new Server(); } }
Client Side
import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; import java.util.Random; public class Client implements MessageListener { private static int ackMode; private static String clientQueueName; private boolean transacted = false; private MessageProducer producer; static { clientQueueName = "client.messages"; ackMode = Session.AUTO_ACKNOWLEDGE; } public Client() { ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); Connection connection; try { connection = connectionFactory.createConnection(); connection.start(); Session session = connection.createSession(transacted, ackMode); Destination adminQueue = session.createQueue(clientQueueName); //Setup a message producer to send message to the queue the server is consuming from this.producer = session.createProducer(adminQueue); this.producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); //Create a temporary queue that this client will listen for responses on then create a consumer //that consumes message from this temporary queue...for a real application a client should reuse //the same temp queue for each message to the server...one temp queue per client Destination tempDest = session.createTemporaryQueue(); MessageConsumer responseConsumer = session.createConsumer(tempDest); //This class will handle the messages to the temp queue as well responseConsumer.setMessageListener(this); //Now create the actual message you want to send TextMessage txtMessage = session.createTextMessage(); txtMessage.setText("MyProtocolMessage"); //Set the reply to field to the temp queue you created above, this is the queue the server //will respond to txtMessage.setJMSReplyTo(tempDest); //Set a correlation ID so when you get a response you know which sent message the response is for //If there is never more than one outstanding message to the server then the //same correlation ID can be used for all the messages...if there is more than one outstanding //message to the server you would presumably want to associate the correlation ID with this //message somehow...a Map works good String correlationId = this.createRandomString(); txtMessage.setJMSCorrelationID(correlationId); this.producer.send(txtMessage); } catch (JMSException e) { //Handle the exception appropriately } } private String createRandomString() { Random random = new Random(System.currentTimeMillis()); long randomLong = random.nextLong(); return Long.toHexString(randomLong); } public void onMessage(Message message) { String messageText = null; try { if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; messageText = textMessage.getText(); System.out.println("messageText = " + messageText); } } catch (JMSException e) { //Handle the exception appropriately } } public static void main(String[] args) { new Client(); } }
Protocol Class
This class is needed to run the client/server example above. Delegating the handling of messages to a seperate class is solely a personal preference.
public class MessageProtocol { public String handleProtocolMessage(String messageText) { String responseText; if ("MyProtocolMessage".equalsIgnoreCase(messageText)) { responseText = "I recognize your protocol message"; } else { responseText = "Unknown protocol message: " + messageText; } return responseText; } }
发表评论
-
自增 自减 java和c的区别
2012-03-10 15:57 1379JAVA public class Test { ... -
瞎聊系统性能优化
2012-02-19 23:46 1087一个系统中影响性能的无非就是CPU计算能力,磁盘、网络的读写能 ... -
在tomcat中,通过IP访问web系统,不需要端口号的方法(转)
2012-02-06 11:10 8844源文章地址:http://sinian.iteye.com/b ... -
java 编码
2012-02-02 18:23 1123先看一个字符串 String str = &qu ... -
javassist与classLoader
2012-02-02 15:22 4253javassist.jar是个非常 ... -
tcp 和 java socket
2011-12-31 12:52 2766tcp socket 总结点 1 ... -
netty 疑惑
2011-12-01 18:27 2639netty的nio 模式如下 一个线程Boss使用 ... -
Apache Tomcat http_proxy 连接方式配置
2011-11-02 18:03 55391、安装Tomcat ,为了使域名保持一致,在conf\Cat ... -
谈线程池
2011-10-27 12:47 1493线程池原理:用指定数 ... -
设置tomcat启动参数
2011-09-15 16:58 1458window: 在catalina.bat 文件的开始处添加如 ... -
通过反汇编class看i++和++i的区别
2011-08-17 14:32 2052public void method4() ... -
hotspot 控制参数
2011-08-17 09:25 1250文档来源于 http://www.oracle.com ... -
Spring 事务异常回滚
2011-08-16 10:10 11057先看如下代码 @Transactional ... -
java IO和NIO测试
2011-08-11 12:08 1574测试环境:cpu:Q9500 4核 频率2.83GHZ ... -
静态锁和实例锁
2011-07-28 18:21 1915Java中可以对静态方法和实例方法使用synchroni ... -
BASE64 和Dom4j
2011-07-20 09:45 1251项目当中用到MD5做消息摘要,后通过BASE64转成字符 ... -
jetty httpServer和java6内置httpServer比较
2011-07-19 12:03 3018测试情况是客户端100个线程同时同时请求10000次,服务器端 ... -
Jetty HttpClent 异常
2011-07-15 13:48 1190使用Jetty HttpClent做异步请求,结果发现这 ... -
关于Hibernate延迟加载
2011-07-14 17:42 1056package com.lottery.test; ... -
Jetty内嵌Http服务器
2011-07-14 11:13 3339本例只是以HttpServlet方式实现,更多的方式可以通过h ...
相关推荐
activeMQ JMS WEB 例子
ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息...ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
利用ActiveMQ中间件发送JMS消息的例子
jms 案例对于初学者很有用的偶,很简单很使用的例子
一个小程序让你快速入门JMS ActiveMQ MQ 消息队列。记录下来方便以后自己查询学习。
该例子是本人写的一个关于使用springMVC搭建的activeMQ的JSM实例,希望对学校JMS的朋友有所帮助。
activeMQ完整例子
jms测试程序,将tomcat和activeMq整合在一起做的一个发送接受的发布订阅的例子
activemq基于web的例子
这个Demo程序演示了如何使用SpringBoot来构建一个最简单的基于ActiveMQ的JMS程序。
Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件;由于ActiveMQ是一个纯Java程序,因此只需要操作系统支持Java虚拟机,ActiveMQ便可执行。
JMS教程+activemq以及activemq和tomcat整合中的例子跑不起来,现已修改,在这里下载可以跑的例子。
学习jms+active+spring过程中自己写的一些简单例子,详情可见博文http://blog.csdn.net/dream_broken/article/details/43759911
JMS、ActiveMQ入门及深入使用的例子,这些例子都是我测试的
activemq-web-console的默认使用方式是通过在...2.一个是demo,有一些使用jms和activemq的简单例子。 3.还有一个fileserver,用来支持通过activemq发送文件时的中转服务器。blob message时配置的http文件服务器。
最全的基于spring mvc的JMS+activeMQ实现的消息中间件代码例子,源程序和apache-activemq-5.10.0-bin.zip
NULL 博文链接:https://zhaoshijie.iteye.com/blog/2090954
SpringMvc+redis+activeMq实现消息发布订阅(测试通过) redis和activeMq jms各自需要的Jar包在其它资源中上传,大家可以下载。 这个例子拿到项目中可直接用
ActiveMQ 不仅实现了 JMS 规范中定义的所有特性,也额外提供了一些特有且有用的特性。我们会在 3.1 小节详细列说这些特性,并且书中剩余的章节还会继续讨论这些特性。为了演示这些特性,我们创建了两个基于实际业务...