queueBrowser.GetEnumerator()未获取任何消息| IBM MQ XMS C#客户端
我们正在使用IBM MQ XMS C#client Version 9.0(在.NET 4.6.2框架上)与IBM MQ协作。我只需要知道给定队列中的所有消息,而无需将它们从队列中移除queueBrowser.GetEnumerator()未获取任何消息| IBM MQ XMS C#客户端,c#,ibm-mq,xms,C#,Ibm Mq,Xms,我们正在使用IBM MQ XMS C#client Version 9.0(在.NET 4.6.2框架上)与IBM MQ协作。我只需要知道给定队列中的所有消息,而无需将它们从队列中移除 XMSFactoryFactory xMSFactoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ); // Create WMQ Connection Factory. IConnectionFacto
XMSFactoryFactory xMSFactoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
// Create WMQ Connection Factory.
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");
// Create connection.
connectionWMQ = connectionFactory.CreateConnection();
connectionWMQ.ExceptionListener = new ExceptionListener(OnXMSException);
// Create session
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();
--end of the method
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(textMessage);
}
}
}
}
我们还让消费者排队。需要消费者和浏览器协同工作。浏览器不应删除消息,但仍需要获取所有消息
所以我设置了一个QueueBrowser,如下所示,但是QueueBrowser.GetEnumerator()根本不获取消息 如果使用相同的代码创建MessageConsumer并附加一个侦听器,它将把消息发布到队列中。因此,问题仅限于浏览器 有人能指出为什么会发生这样的事吗。为什么queueEnumerator.MoveNext()总是返回false,表示队列中没有消息
XMSFactoryFactory xMSFactoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
// Create WMQ Connection Factory.
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");
// Create connection.
connectionWMQ = connectionFactory.CreateConnection();
connectionWMQ.ExceptionListener = new ExceptionListener(OnXMSException);
// Create session
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();
--end of the method
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(textMessage);
}
}
}
}
OP在评论中提到了以下几点:我们让消费者作为商业案例的一部分阅读消息,并希望设置浏览器,以便我们只获取消息的副本,以便我们可以在单独的应用程序中跟踪消息,以记录收到的所有消息 我在下面提供一些选项
选项1 不要仅仅为了记录收到的消息而使用单独的应用程序,而是让您的“业务案例”应用程序记录消息,作为处理的一部分
选项2 设置两个队列,第一个队列将接收入站消息,并由记录消息的应用程序使用,然后将其副本放入第二个队列,该队列将由“业务案例”应用程序使用
选项3 使用IBM MQ发布/订阅功能创建消息的两个副本,其中一个副本将由记录消息的应用程序使用,另一个副本将由“业务案例”应用程序使用。注意,这只复制消息体,而MQ消息描述符(MQMD)是关于消息的元数据(如放置时间、放置日期、消息id、用户id)不会被复制。许多应用程序不查看MQMD,因此对您来说可能不是问题 设置如下所示: 为入站邮件创建
QALIAS
,此别名将通过指定目标为主题对象来指向主题字符串:
DEFINE QALIAS(INBOUND.QUEUE) TARGET(INBOUND.TOPIC) TARGTYPE(TOPIC)
定义主题
对象:
DEFINE TOPIC(INBOUND.TOPIC) TOPICSTR(INBOUND/TOPIC)
创建两个QLOCAL
对象,一个由记录消息的应用程序使用,另一个由“业务案例”应用程序使用:
DEFINE QLOCAL(INBOUND.QUEUE.LOGGER)
DEFINE QLOCAL(INBOUND.QUEUE.PROCESSOR)
DEFINE QLOCAL(INBOUND.QUEUE)
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
对象,其中一个是入站消息队列,您可以从该队列读取一个程序,然后将消息副本写入其他两个队列。Capitalware维护了一个名为的开源工具,它可以从源队列读取数据并写入一个或多个队列,这确实会复制MQMD和消息体
设置如下所示:
创建三个QLOCAL
对象,第一个对象由应用程序使用,该应用程序将复制到第二个对象,该应用程序将记录消息,第三个对象由“业务案例”应用程序使用:
DEFINE QLOCAL(INBOUND.QUEUE.LOGGER)
DEFINE QLOCAL(INBOUND.QUEUE.PROCESSOR)
DEFINE QLOCAL(INBOUND.QUEUE)
DEFINE QLOCAL(INBOUND.QUEUE.LOGGER)
DEFINE QLOCAL(INBOUND.QUEUE.PROCESSOR)
选项5 有一个名为的商业产品,它可以使用MQ API出口将发送到“业务案例”应用程序队列的消息精确复制到一个或多个其他队列。我个人没有使用过这个,但是设置将只是两个QLOCAL队列,第一个队列将由“business case”应用程序使用,第二个队列将由记录消息的应用程序使用
DEFINE QLOCAL(INBOUND.QUEUE)
DEFINE QLOCAL(INBOUND.QUEUE.LOGGER)
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;
}
}
}
}
}
我只是稍微修改了你的代码,我可以浏览这些消息
DEFINE QLOCAL(INBOUND.QUEUE)
DEFINE QLOCAL(INBOUND.QUEUE.LOGGER)
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;
}
}
}
}
}
我安装了完整的MQ v9客户端。在同一队列上设置了队列浏览器和队列使用者。因此,队列使用者甚至在队列浏览器出现之前就已经删除了消息。一旦我停止队列使用者,队列浏览器就能够接收消息。但现在我的问题是如何确保队列浏览器和队列消费者同时工作。作为商业案例的一部分,我们有消费者正在运行以阅读邮件,并希望设置浏览器,以便我们只获取邮件的副本,以便我们可以在单独的应用程序中跟踪邮件,以记录收到的所有邮件。我编辑了问题,以包括:除了邮件浏览器外,还有并发邮件消费者。是否使用此浏览器在并发使用者工作时获取消息。我认为,当消息消费者被设置在队列上时,浏览器将无法获取消息,这一点很明显。使用者从队列中删除消息。浏览器无法获取删除的邮件。我喜欢我的商业案例的“选项1”。谢谢您的接受。你还会赏金吗?