Java 发送方/接收方之间的JMS消息流

Java 发送方/接收方之间的JMS消息流,java,jms,message-queue,Java,Jms,Message Queue,如果我使用以下代码创建发送者和接收者 qsender = qsession.createSender((Queue)msg.getJMSDestination()); qreceiver=qsession.createReceiver((Queue)msg.getJMSDestination()); 然后再这样做 qsender.send(msg); 它是否只是将消息发送到队列中,并且将永远留在队列中?我需要在接收方调用receive方法还是实现MessageListener接口才能将其发送

如果我使用以下代码创建发送者和接收者

qsender = qsession.createSender((Queue)msg.getJMSDestination());
qreceiver=qsession.createReceiver((Queue)msg.getJMSDestination());
然后再这样做

qsender.send(msg);
它是否只是将消息发送到队列中,并且将永远留在队列中?我需要在接收方调用receive方法还是实现MessageListener接口才能将其发送给接收方

编辑:更多信息

qsender = qsession.createSender((Queue)msg.getJMSDestination());
qreceiver=qsession.createReceiver((Queue)msg.getJMSDestination());

temp1 = qsession.createTemporaryQueue();
responseConsumer = qsession.createConsumer(temp1);
msg.setJMSReplyTo(temp1);

responseConsumer.setMessageListener(responseListener);
msg.setJMSCorrelationID(msg.getJMSCorrelationID()+i);

qsender.send(msg);

在上面的代码中,临时队列用于什么?是用来接收信息的吗?是听筒吗?如果是,msg.setJMSReplyTotemp1有什么用途

是,发送。。方法将消息发送到目标队列。这个消息将一直保留在队列中,直到您的程序使用receiver接收到它,或者直到您的MessageBroker正在运行

关于第二个问题,两种方法的区别在于:

收到。。方法是同步的,这是这种方法的一个缺点。这意味着接收方必须耐心等待消息到达,因为接收消息将阻塞,直到消息可用或出现超时情况。另一方面,使用侦听器消费消息是异步过程。你的听筒等不及了。只有当消息被放入查询时,侦听器才会调用您的接收方法

更新:

临时目的地用于消费者发送消息回复。例如,您的服务器从客户机收到消息,您需要向他发送响应。在这种情况下,您应该使用临时目的地。服务器应用程序将在您的案例中使用此临时目标队列向客户端发送响应消息。此类队列的作用域仅限于创建它的连接,一旦连接关闭,就会在服务器端将其删除

您可以在和中找到更多详细信息。在第二篇文章中,还描述了如何以及何时使用JMSCorrelationID

下面是官方文档中有趣的部分,描述了如何使用临时目的地发送响应消息:

您可以使用临时目的地来实现简单的请求/回复 机械装置如果创建临时目标并将其指定为 发送消息时JMSReplyTo消息头字段的值, 然后消息的使用者可以使用JMSReplyTo的值 字段作为其发送答复的目的地。消费者可以 还可以通过设置JMSCorrelationID来引用原始请求 JMSMessageID值的回复消息的标头字段 请求的标头字段。例如,onMessage方法可以 创建一个会话,以便它可以发送对所发送消息的回复 收到。它可以使用如下代码:

更新2:

我想澄清我对队列或主题中消息过期时间的回答。默认情况下,消息永远不会过期。但您可以设置邮件的过期时间:

producer.setTimeToLive(60000);
在此之后,此MessageProducer生成的所有消息都将具有指定的过期时间

此外,您还可以在具体消息发送期间为其指定过期时间:

producer.send(message, DeliveryMode.NON_PERSISTENT, 3, 10000);

其中10000表示10秒

是,发送。。方法将消息发送到目标队列。这个消息将一直保留在队列中,直到您的程序使用receiver接收到它,或者直到您的MessageBroker正在运行

关于第二个问题,两种方法的区别在于:

收到。。方法是同步的,这是这种方法的一个缺点。这意味着接收方必须耐心等待消息到达,因为接收消息将阻塞,直到消息可用或出现超时情况。另一方面,使用侦听器消费消息是异步过程。你的听筒等不及了。只有当消息被放入查询时,侦听器才会调用您的接收方法

更新:

临时目的地用于消费者发送消息回复。例如,您的服务器从客户机收到消息,您需要向他发送响应。在这种情况下,您应该使用临时目的地。服务器应用程序将在您的案例中使用此临时目标队列向客户端发送响应消息。此类队列的作用域仅限于创建它的连接,一旦连接关闭,就会在服务器端将其删除

您可以在和中找到更多详细信息。在第二篇文章中,还描述了如何以及何时使用JMSCorrelationID

下面是官方文档中有趣的部分,描述了如何使用临时目的地发送响应消息:

您可以使用临时目的地来实现简单的请求/回复 机械装置如果创建临时目标并将其指定为 发送消息时JMSReplyTo消息头字段的值, 然后消息的使用者可以使用JMSReplyTo的值 字段作为它向其发送repl的目标 Y消费者可以 还可以通过设置JMSCorrelationID来引用原始请求 JMSMessageID值的回复消息的标头字段 请求的标头字段。例如,onMessage方法可以 创建一个会话,以便它可以发送对所发送消息的回复 收到。它可以使用如下代码:

更新2:

我想澄清我对队列或主题中消息过期时间的回答。默认情况下,消息永远不会过期。但您可以设置邮件的过期时间:

producer.setTimeToLive(60000);
在此之后,此MessageProducer生成的所有消息都将具有指定的过期时间

此外,您还可以在具体消息发送期间为其指定过期时间:

producer.send(message, DeliveryMode.NON_PERSISTENT, 3, 10000);
其中10000表示10秒

是的,它将始终保留在队列中,直到它被消费或手动或强制从队列中删除为止。这就是JMS的耐久性特性,这就是为什么它比RPC更受欢迎

关于receive方法,它是一个同步方法,将阻塞线程,直到它接收到要使用的消息

关于消息侦听器实现,它遵循基于拉的模型。MessageBroker在一段时间后继续查询JMS服务器,以查看是否有要使用的消息

选项3和选项4的选择取决于需求,阻塞线程有其自身的缺点,不会让任何事情发生,轮询也有其自身的缺点,特别是当Jms服务器作为远程机器上的独立服务器运行时,代理必须在一段时间后使用RMI查询消息

UPDATE::如果您查看企业集成请求/应答模式,它们已经解释了这一点,因为消息传递使用异步过程,因此没有来自另一端的确认。如果要向发送方发送关于消息的确认,可以使用msg.setJMSReplyTo,它使用确认消息相关id与发送方消息id匹配,以同步请求响应

谈到临时队列,它提供了在运行时创建绑定到给定连接的队列的好处,而不是在部署时静态定义队列,其优点是它提供了轻量级替代方案,并有助于在很大程度上扩展系统

是的,它将始终保留在队列中,直到它被消费或手动或强制从队列中删除为止。这就是JMS的耐久性特性,这就是为什么它比RPC更受欢迎

关于receive方法,它是一个同步方法,将阻塞线程,直到它接收到要使用的消息

关于消息侦听器实现,它遵循基于拉的模型。MessageBroker在一段时间后继续查询JMS服务器,以查看是否有要使用的消息

选项3和选项4的选择取决于需求,阻塞线程有其自身的缺点,不会让任何事情发生,轮询也有其自身的缺点,特别是当Jms服务器作为远程机器上的独立服务器运行时,代理必须在一段时间后使用RMI查询消息

UPDATE::如果您查看企业集成请求/应答模式,它们已经解释了这一点,因为消息传递使用异步过程,因此没有来自另一端的确认。如果要向发送方发送关于消息的确认,可以使用msg.setJMSReplyTo,它使用确认消息相关id与发送方消息id匹配,以同步请求响应


谈到临时队列,它提供了在运行时创建队列(绑定到给定连接)的好处,而不是在部署时静态定义队列,优点是它提供了轻量级的替代方案,并有助于在很大程度上扩展系统。

这意味着如果我不显式调用receive方法或实现MessageListener,它将永远留在队列中?我创建了一个临时队列,为它创建了一个MessageConsumer,设置了一个JMS ReplyTo,并为它设置了一个MessageListener。它在临时队列中获取响应。我的问题-如果没有发送给接收者,我们如何获得响应?注意-未调用receive/implementing MessageListener。关于您的第一个问题-是。它将一直保留,直到您的MessageBroker运行为止。关于第二个问题-请在你的问题中添加一些例子,以便我能更好地理解你。我编辑了我的答案。希望这能帮助你澄清一些事情。另外,我建议您阅读oracle官方文档的第二个链接。这就是我现在正在做的。这意味着如果我不显式调用receive方法或实现MessageListener,它将永远留在队列中?我创建了一个临时队列,为它创建了一个MessageConsumer,设置了一个JMS ReplyTo,并为它设置了一个MessageListener。
它在临时队列中获取响应。我的问题-如果没有发送给接收者,我们如何获得响应?注意-未调用receive/implementing MessageListener。关于您的第一个问题-是。它将一直保留,直到您的MessageBroker运行为止。关于第二个问题-请在你的问题中添加一些例子,以便我能更好地理解你。我编辑了我的答案。希望这能帮助你澄清一些事情。另外,我建议您阅读oracle官方文档的第二个链接。这就是我现在正在做的。