我正在连接IBM Websphere MQ。我希望能够将回复消息与正确的请求消息进行匹配。我已经浏览了数百页来获得这个并且没有运气。
我有一个类 - MQHandler - 它将消息发送到一个已定义的队列,并从另一个队列中读取请求。这很好,但是,如果多个用户同时使用该应用程序,则消息会混淆。
我似乎无法在接收器上获得指示CorrelationID匹配的方法。 有点像...
consumer.receive(selector);
您可以查看以下方法以确保我正确地执行此操作吗?
/**
* When the class is called, this initialisation is done first.
*
* @throws JMSException
*/
public void init() throws JMSException
{
// Create a connection factory
JmsFactoryFactory ff;
try
{
ff = JmsFactoryFactory.getInstance( WMQConstants.WMQ_PROVIDER );
cf = ff.createConnectionFactory();
// Set the properties
cf.setStringProperty( WMQConstants.WMQ_HOST_NAME, hostServer );
cf.setIntProperty( WMQConstants.WMQ_PORT, 1414 );
cf.setStringProperty( WMQConstants.WMQ_CHANNEL, channel );
cf.setIntProperty( WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT );
cf.setStringProperty( WMQConstants.WMQ_QUEUE_MANAGER, qManager );
connection = cf.createConnection();
session = connection.createSession( false, Session.AUTO_ACKNOWLEDGE );
}
catch( JMSException e )
{
throw e;
}
} // end of init
/**
* @param request
* @return
* @throws JMSException
*/
private String sendRequest( String request ) throws JMSException
{
// Create JMS objects
Destination destination = session.createQueue( "queue:///" + writeQueueName );
// Enable write of MQMD fields. See documentation for further
// details.
((JmsDestination) destination).setBooleanProperty( WMQConstants.WMQ_MQMD_WRITE_ENABLED, true );
// Set message context, if needed. See comment at the top.
// Create a producer
MessageProducer producer = session.createProducer( destination );
// Create a message
TextMessage message = session.createTextMessage( request );
// Generate a custom message id
message.setJMSCorrelationID( generateRandomID() );
// Start the connection
connection.start();
// And, send the message
producer.send( message );
System.out.println(message);
return message.getJMSCorrelationID();
}
/**
* @param customMessageId
* @return
* @throws JMSException
*/
private String recvResponse( String customMessageId ) throws JMSException
{
Destination destination = session.createQueue( "queue:///" + readQueueName );
// Enable read of MQMD fields.
((JmsDestination) destination).setBooleanProperty( WMQConstants.WMQ_MQMD_READ_ENABLED, true );
((JmsDestination) destination).setObjectProperty( WMQConstants.JMS_IBM_MQMD_CORRELID, customMessageId );
// Create a consumer
MessageConsumer consumer = session.createConsumer( destination );
// Start the connection
connection.start();
// And, receive a message from the queue
TextMessage receivedMessage = (TextMessage)consumer.receive( 15000 );
connection.close();
session.close();
return receivedMessage.getText();
}
以下是主要方法的片段......
try
{
String customMessageId;
init();
customMessageId = sendRequest( request );
return recvResponse( customMessageId );
}
catch( Exception ex )
{
System.out.println( "Error on MQ." );
throw new Exception( "\n\n*** An error occurred ***\n\n" + ex.getLocalizedMessage()
+ "\n\n**********************************" );
}
答案 0 :(得分:3)
QueueReceiver queueReceiver =
session.createReceiver(destination, "JMSCorrelationID='customMessageId'");
TextMessage receivedMessage = (TextMessage)queueReceiver.receive( 15000 );
在我的示例中,customMessageId应包含您先前设置的实际值。
此外,我已经看到很多情况,人们生成一个correlationID并在出站消息中设置它,期望能够根据该值选择响应。教科书的方法是让服务提供者应用程序在响应时将消息ID复制到相关ID。请求者仍将JMSCorrelationID指定为选择器,但将使用原始JMSMessageID作为值。由于JMSMessageID保证即使在QMgrs中也是唯一的,因此您很可能不会在此值上发生冲突。您需要确保您的客户端与服务提供商的行为相匹配,以确定将哪个值复制到相关ID中。
答案 1 :(得分:1)
这可能是临时队列的一个用例,它只与创建它的连接相关联。
onJava上有一篇详细文章,Designing Messaging Applications with Temporary Queues
“临时目的地(temporary queues或临时主题)是 建议作为轻量级替代品 在可扩展的系统架构中 可以用作唯一目的地 回复。这样的目的地有一个 范围仅限于连接 创建它,并删除 服务器端尽快连接 已关闭。“
和Java文档解释:
您可以使用临时目的地 实现简单的请求/回复 机制。如果你创建一个临时的 目的地并将其指定为 JMSReplyTo消息头的值 发送邮件的字段, 消息的消费者可以使用 JMSReplyTo字段的值为 它发送回复的目的地 并且还可以参考原文 通过设置请求 JMSCorrelationID头部字段 回复消息的值 JMSMessageID的头字段 请求。