例如,我有具有REQUESTQ和RESPONSEQ的IBM MQ,将请求提交给REQUESTQ时,我需要从RESPONSEQ获取响应。根据以下代码:
package requestReply;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import com.ibm.msg.client.jms.JmsConnectionFactory;
import com.ibm.msg.client.jms.JmsFactoryFactory;
import com.ibm.msg.client.wmq.WMQConstants;
/*
* Implementation of requester class
*/
class Requestor implements Runnable {
private Thread t;
private String threadName;
Requestor( String name){
threadName = name;
System.out.println("Creating Thread:" + threadName );
}
public void run() {
JmsConnectionFactory cf = null;
Connection connection = null;
Session session = null;
Destination reqQ = null;
Destination repQ = null;
MessageProducer producer = null;
MessageConsumer consumer = null;
try {
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
cf = ff.createConnectionFactory();
// Set the properties
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_BINDINGS);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, "QM2");
// Create JMS objects
connection = cf.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create destination to send requests
reqQ = session.createQueue("queue:///REQUESTQ");
// Create destination to read replies
repQ = session.createQueue("queue:///REPLYQ");
// Create producer
producer = session.createProducer(reqQ);
// Create a request message
Message requestMessage = session.createTextMessage("Requesting a service");
// Tell the responder where to put replies.
requestMessage.setJMSReplyTo(repQ);
// Send it off
producer.send(requestMessage);
// Get only that reply that matches my request message id.
String selector = "JMSCorrelationID='" + requestMessage.getJMSMessageID()+"'";
// Create consumer with selector
consumer = session.createConsumer(repQ, selector);
// Start the connection
connection.start();
// Get the message
Message receivedMessage = consumer.receive(35000);
if(receivedMessage != null)
System.out.println("\nRequestor received message:\n" + receivedMessage);
else
System.out.println("No message received");
}catch(Exception ex){
System.out.println(threadName);
System.out.println(ex);
}
}
// Start thread
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
/*
* Implementation of Responder class
*/
class Responder implements Runnable {
private Thread t;
private String threadName;
Responder( String name){
threadName = name;
System.out.println("Creating Thread: " + threadName );
}
public void run() {
JmsConnectionFactory cf = null;
Connection connection = null;
Session session = null;
Destination reqQ = null;
Destination repQ = null;
MessageProducer producer = null;
MessageConsumer consumer = null;
try {
// Create a connection factory
JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
cf = ff.createConnectionFactory();
// Set the properties
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_BINDINGS);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, "QM2");
// Create JMS objects
connection = cf.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
reqQ = session.createQueue("queue:///REQUESTQ");
// Create consumer to read requests
consumer = session.createConsumer(reqQ);
// Start the connection
connection.start();
// Loop to read requests and respond
while(true){
Message receivedMessage = consumer.receive(35000);
if(receivedMessage != null){
System.out.println("\nResponder received message:\n" + receivedMessage);
repQ = receivedMessage.getJMSReplyTo();
producer = session.createProducer(repQ);
Message requestMessage = session.createTextMessage("Responder service");
requestMessage.setJMSCorrelationID(receivedMessage.getJMSMessageID());
producer.send(requestMessage);
}
else
System.out.println("No message received");
}
}catch(Exception ex){
System.out.println(threadName);
System.out.println(ex);
}
}
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
public class ReqRep {
public static void main(String[] args) {
// TODO Auto-generated method stub
Requestor req = new Requestor( "Requester");
req.start();
Responder rep = new Responder( "Responder");
rep.start();
}
}
[代码从https://www.ibm.com/developerworks/community/blogs/messaging/entry/jms_request_reply_sample?lang=en]复制
我从这段代码中了解到,当Requestor
线程向REQUESTQ
提交请求时,Responder
将从REQUESTQ
中提取信息并重新发送到RESPONSEQ
,因此Requestor
可以从RESPONDERQ
获得实际响应?
我之所以这样问,是因为当我实际尝试时,Requestor
和Responder
总是挂起以获得响应,这对我来说很有意义,因为一旦请求位于REQUESTQ
中,MQ服务已经摆脱了该消息,对其进行了处理并已推送到RESPONSEQ
,并且由于Requester
正在等待Responder
,并且Responder
无法提取任何内容来自REQUESTQ
的内容,导致挂起。 (如果我错了,请纠正我)
答案 0 :(得分:0)
在我的机器上对其进行了尝试,有时它可以按预期运行,有时挂起35秒钟,直到消息传播为止。
启动Responder
时,这是一个计时问题。如果Connection
和Session
设置得太早,它将看不到前receive
中的消息,只有在等待的前35秒之后才能收到消息。为了克服这个问题,只需在req.start()
和rep.start()
之间稍等一下,然后它就会持续工作。
我建议阅读IBM的官方教程,例如Point to point with JMS。另外,它使用JMS 2.0,使JMS编程更简单。