queueBrowser.GetEnumerator()未获取任何消息| IBM MQ XMS C#客户端

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

我们正在使用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.
        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”。谢谢您的接受。你还会赏金吗?