1

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

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.setJMSReplyTo(temp1)

4

2 回答 2

2

是的,send(..) 方法会将消息发送到目标队列。并且此消息将保留在队列中,直到您的程序使用接收器接收它或直到您的消息代理正在运行(据我所知)。

关于你的第二个问题,那么两种方法之间的区别在于下一个:

receive (..) 方法是同步的(这是这种方法的缺点)。这意味着接收者必须耐心等待消息到达,因为receive () 消息将阻塞,直到有消息可用(或直到发生超时条件)。从另一端使用侦听器消费消息是异步过程。您的接收器不会等待。只有在将消息放入查询时,侦听器才会调用您的接收方法。

更新:

临时目的地用于发送消费者对消息的回复。例如,您的服务器从客户端获取消息并且您需要向他发送响应的情况。在这种情况下,您应该使用临时目的地。服务器应用程序将使用此临时目标(在您的情况下为队列)向客户端发送响应消息。此类队列的范围仅限于创建它的连接,并在连接关闭后立即在服务器端删除。

您可以在本文officila java 教程中找到更多详细信息。在第二篇文章中还介绍了如何以及何时使用 JMSCorrelationID。

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

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

producer = session.createProducer(msg.getJMSReplyTo());
replyMsg = session.createTextMessage("Consumer " +
    "processed message: " + msg.getText());
replyMsg.setJMSCorrelationID(msg.getJMSMessageID());
producer.send(replyMsg);

更新 2:

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

producer.setTimeToLive(60000);

在此之后,此 MessageProducer 生成的所有消息都将具有指定的到期时间。

您还可以在发送期间指定具体消息的到期时间:

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

其中 10000 表示 10 秒

于 2012-08-16T06:27:17.510 回答
2
  1. 是的,它将始终保留在队列中,直到它被消耗或手动或强制从队列中删除。这就是 JMS 的持久性属性,这就是它优于 RPC 的原因。

  2. 关于receive方法,它是一个同步方法,会阻塞线程,直到收到要消费的消息。

  3. 关于消息监听器的实现,它遵循基于拉的模型。消息代理会在一段时间后继续查询 JMS 服务器,以查看是否有要消费的消息。

  4. 从选项 3 和选项 4 中选择取决于要求,阻塞线程有其自身的缺点,不会让任何事情进一步发展,而轮询也有其自身的缺点,特别是如果 Jms 服务器作为远程机器上的独立服务器运行时,并且代理必须在一段时间后使用 RMI 来查询消息。

更新 ::如果您查看企业集成请求/回复模式EIP,他们已经解释说,因为消息传递使用异步过程,因此没有来自另一端的确认。如果您想向发件人发送关于消息的确认,您可以使用msg.setJMSReplyTo它使用确认消息 Correlation id 与发件人消息 id 匹配以同步请求响应。

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

于 2012-08-16T06:52:29.240 回答