queueBrowser.GetEnumerator()没有得到任何消息IBM MQ XMS C#客户端

时间:2017-10-27 16:10:11

标签: c# ibm-mq xms

我们正在使用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(文字信息);
 }
 }
 }
 }
  



2 个答案:

答案 0 :(得分:2)

OP在评论中提到了以下内容:我们让消费者在运行时将消息作为业务案例的一部分进行阅读,并希望设置浏览器以便我们只获取消息的副本,以便我们可以在将所有收到的消息分开的应用程序。

我在下面提供了一些选项。

选项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.LOGGERINBOUND.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;
            }
        }
       }
    }
}