我们正在使用IBM MQ XMS C#client ver 9.0(在.NET 4.6.2框架上)来使用IBM MQ。我只需要知道给定队列上的所有消息而不将它们从队列中删除。


我们还为队列设置了消费者。需要消费者和浏览器协同工作。浏览器不应删除邮件,但仍需要获取所有邮件。


所以我设置了如下所示的QueueBrowser,但是queueBrowser.GetEnumerator()根本没有收到消息。


使用相同的代码创建MessageConsumer并附加一个监听器,它将获得发布队列的消息。所以QueueBrowser只会出现问题。


任何人都可以指出为什么会这样发生。为什么queueEnumerator.MoveNext()总是返回false,表示队列中没有消息。


 XMSFactoryFactory xMSFactoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);&#xA ;
 //创建WMQ连接工厂。
 IConnectionFactory connectionFactory = xMSFactoryFactory.CreateConnectionFactory();

 connectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME,“hostname”);
 connectionFactory.SetIntProperty(XMSC.WMQ_PORT,portNumber);
 connectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL,“channelName”);
 connectionFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE,XMSC.WMQ_CM_CLIENT);
 connectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER,“QueueManagerName”);

 //创建连接。
 connectionWMQ = connectionFactory.CreateConnection();
 connectionWMQ.ExceptionListener = new ExceptionListener(OnXMSException);

 //创建会话
 ISession sessionWMQ = connectionWMQ.CreateSession(false,AcknowledgeMode.AutoAcknowledge);

 IDestination destination = sessionWMQ.CreateQueue(“QueueName”); 


 IQueueBrowser queueBrowser = sessionWMQ.CreateBrowser(destination);

 connectionWMQ.Start();

 Thread thread = new Thread(KeepBrowsingMessaegs);
 thread.Start();

 - 方法的结尾

 private void KeepBrowsingMessaegs()
 {
 IEnumerator queueEnumerator = queueBrowser.GetEnumerator();
 while(!cancellationTokenSource.IsCancellationRequested)
 {

 if(queueEnumerator.MoveNext())
 {
 ITextMessage textMessage = queueEnumerator.Current as ITextMessage;
 if(textMessage!= null)
 {
 System.Diagnostics.Trace.Write(文字信息);
 }
 }
 }
 }
 代码>


答案 0 :(得分:2)
我在下面提供了一些选项。
选项1
没有单独的应用程序只是为了记录收到的消息,而是让您的“业务案例”应用程序在处理过程中记录消息。
选项2
设置两个队列,第一个队列将接收入站消息并被应用程序使用,该应用程序将记录消息,然后将其副本放到第二个队列中,该队列将由“业务案例”应用程序使用。
选项3
使用IBM MQ发布/订阅功能创建消息的两个副本,其中一个将由记录消息的应用程序使用,另一个将由“业务案例”应用程序使用。请注意,这仅复制消息正文,MQ消息描述符(MQMD)是关于消息的元数据(诸如put time,put date,message id,userid之类的东西)将不会重复。许多应用程序不会查看MQMD,因此对您来说可能不是问题。
设置如下:
为入站邮件创建QALIAS
,此别名将通过指定目标是主题对象指向主题字符串:
DEFINE QALIAS(INBOUND.QUEUE) TARGET(INBOUND.TOPIC) TARGTYPE(TOPIC)
定义TOPIC
对象:
DEFINE TOPIC(INBOUND.TOPIC) TOPICSTR(INBOUND/TOPIC)
创建两个QLOCAL
个对象,一个用于记录消息的应用程序,另一个用于“业务案例”应用程序:
DEFINE QLOCAL(INBOUND.QUEUE.LOGGER)
DEFINE QLOCAL(INBOUND.QUEUE.PROCESSOR)
定义两个管理SUBSCRIPTION
对象,以将两个队列都订阅到主题主题字符串:
DEFINE SUB(INBOUND.QUEUE.LOGGER.SUB) TOPICSTR(INBOUND/TOPIC) DEST(INBOUND.QUEUE.LOGGER)
DEFINE SUB(INBOUND.QUEUE.PROCESSOR.SUB) TOPICSTR(INBOUND/TOPIC) DEST(INBOUND.QUEUE.PROCESSOR)
上述设置的结果是,每个发送到名为INBOUND.QUEUE
的队列的邮件都会将副本发布到两个队列INBOUND.QUEUE.LOGGER
和INBOUND.QUEUE.PROCESSOR
。
选项4
您可以设置三个QLOCAL
个对象,一个是入站消息的队列,您可以从该队列中读取一个程序,然后将该消息的副本写入另外两个队列。有一个名为Message Multiplexer (MMX)的Capitalware维护的开源工具可以从源队列读取并写入一个或多个队列,这确实会复制MQMD和消息体。
设置如下:
创建三个QLOCAL
个对象,第一个用于使用应用程序的应用程序,该应用程序将复制到将记录消息的应用程序使用的第二个应用程序,以及由您的“业务案例”使用的第三个应用程序“申请:
DEFINE QLOCAL(INBOUND.QUEUE)
DEFINE QLOCAL(INBOUND.QUEUE.LOGGER)
DEFINE QLOCAL(INBOUND.QUEUE.PROCESSOR)
选项5
有一个名为MQ Message Replication (MQMR)的商业产品可以使用MQ API出口将发送到“业务案例”应用程序队列的消息的精确副本发送到一个或多个其他队列。我没有亲自使用过这个,但是设置只是两个QLOCAL队列,第一个将由你的“业务案例”应用程序使用,第二个将被记录消息的应用程序使用。
DEFINE QLOCAL(INBOUND.QUEUE)
DEFINE QLOCAL(INBOUND.QUEUE.LOGGER)
答案 1 :(得分:1)
我只是稍微调整了一下你的代码,我就可以浏览这些消息了。
namespace XmsBrowser
{
class BrowseMessages
{
IConnection connectionWMQ;
IQueueBrowser queueBrowser;
static void Main(string[] args)
{
BrowseMessages pgm = new BrowseMessages();
pgm.browseMessage();
}
private void browseMessage()
{
try
{
XMSFactoryFactory xMSFactoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
// Create WMQ Connection Factory.
IConnectionFactory connectionFactory = xMSFactoryFactory.CreateConnectionFactory();
connectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, "localhost");
connectionFactory.SetIntProperty(XMSC.WMQ_PORT, 1414);
connectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, "QM_SVRCONN_CHANNEL");
connectionFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
connectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "QMDEMO");
// Create connection.
connectionWMQ = connectionFactory.CreateConnection();
//connectionWMQ.ExceptionListener = new ExceptionListener(OnXMSException);
// Create session
ISession sessionWMQ = connectionWMQ.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
IDestination destination = sessionWMQ.CreateQueue("Q1");
queueBrowser = sessionWMQ.CreateBrowser(destination);
Thread thread = new Thread(KeepBrowsingMessaegs);
thread.Start();
connectionWMQ.Start();
thread.Join();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadKey();
}
private void KeepBrowsingMessaegs()
{
IEnumerator queueEnumerator = queueBrowser.GetEnumerator();
while (true)
{
if (queueEnumerator.MoveNext())
{
ITextMessage textMessage = queueEnumerator.Current as ITextMessage;
if (textMessage != null)
{
System.Diagnostics.Trace.Write(textMessage);
}
}else
{
break;
}
}
}
}
}