2011-02-16 20 views
4

我正在連接到IBM Websphere MQ。我希望能夠將回復消息與正確的請求消息進行匹配。我瀏覽了數百頁來獲得這個,並沒有運氣。如何將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**********************************"); 
    } 

回答

2
QueueReceiver queueReceiver = 
    session.createReceiver(destination, "JMSCorrelationID='customMessageId'"); 

TextMessage receivedMessage = (TextMessage)queueReceiver.receive(15000); 

在我的例子,customMessageId應該包含您以前設置的實際值。

此外,我看到很多情況下,人們生成correlationID並將其設置在出站消息中,希望能夠根據該值選擇響應。教科書這樣做的方式是服務提供商應用程序在響應時將消息ID複製到相關ID。請求者仍然會指定JMSCorrelationID作爲選擇器,但會使用原始的JMSMessageID作爲值。由於即使跨QMgrs,JMSMessageID也保證是唯一的,所以你不太可能碰到這個值。您需要確保您的客戶端匹配服務提供商的行爲,以確定哪些值會被複制到關聯ID中。

1

這可能是一個臨時隊列的用例,它只與創建它的連接相關聯。

有一個在ONJava的一個的相關詳細的文章,Designing Messaging Applications with Temporary Queues

「臨時目標(temporary queues或臨時主題)是一個可擴展的系統架構提出了作爲一個輕量級替代 是 可以作爲唯一的目的地 爲答覆。這樣的目標有一個 範圍僅限於連接該 創造了它,並儘快在 服務器端去除 被關閉了連接「

和Java文檔解釋:

您可以使用臨時目的地 實施一個簡單的請求/回覆 機制。如果你創建一個臨時 目的地,並指定爲JMSReplyTo消息頭 場的 值當您發送郵件時, 消費消息的可用JMSReplyTo字段的 值作爲 目的地,它發送一個回覆 ,並且還可以通過 應答消息的 JMSCorrelationID頭字段設置爲 請求的 JMSMessageID按報頭字段的值引用原始 請求。

相關問題