Sending message on IBM MQ: Hangs on AccessQueue

2019-08-21 10:45发布

问题:

We're trying to send a message on an IBM MQ Message Queue.

We can contact the Queue Manager, but as soon as we call the MQMessage constructor, the process hangs. We suspect that this is actually because whatever AccessQueue is doing is failing.

        using (MQQueueManager qMgr = new MQQueueManager(queueManagerName, connectionProperties))
        {
            // Set up the options on the queue we want to open
            int openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING; 

            // Now specify the queue that we want to open,and the open options
            MQQueue system_default_local_queue =
                qMgr.AccessQueue(sendQueueName, openOptions); // we suspect this is actually where things are wrong

            // Define a WebSphere MQ message, writing some text in UTF format
            MQMessage mqMessage = new MQMessage(); // ** THIS HANGS
            mqMessage.WriteUTF(text);

            // Specify the message options
            MQPutMessageOptions pmo = new MQPutMessageOptions(); // accept the defaults,
            // same as MQPMO_DEFAULT

            // Put the message on the queue
            system_default_local_queue.Put(mqMessage, pmo);

            system_default_local_queue.Close();

            // Disconnect from the queue manager
            qMgr.Disconnect();
        }

Is there an option we're not including or something we're missing?

We're using the the NuGet package WebSphereMqClient v8.0.0.7.


Update:

I'll include our connection properties for completeness based on feedback.

        Hashtable connectionProperties = new Hashtable();
        connectionProperties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
        connectionProperties.Add(MQC.USE_MQCSP_AUTHENTICATION_PROPERTY, true);
        // Set up the rest of the connection properties, based on the
        // connection type requested
        // this is all for MQC.TRANSPORT_MQSERIES_MANAGED
        connectionProperties.Add(MQC.HOST_NAME_PROPERTY, "myserver.com");
        connectionProperties.Add(MQC.CHANNEL_PROPERTY, "MY.CHANNEL");
        connectionProperties.Add(MQC.PORT_PROPERTY, 3223);
        connectionProperties.Add(MQC.CONNECT_OPTIONS_PROPERTY, MQC.MQCNO_RECONNECT_Q_MGR);

In answer to a question from Roger, this is a Managed Queue.

回答1:

You don't show us your connection properties, so I don't know if you set everything correctly. Did you make sure you set 'managed mode'? Also, why aren't you doing any print-outs of what the code has completed?

Here is a complete and working C# .NET/MQ program that uses 'managed mode' connection.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using IBM.WMQ;

/// <summary> Program Name
/// MQTest51
///
/// Description
/// This C# class will connect to a remote queue manager
/// and put a message to a queue under a managed .NET environment.
///
/// Sample Command Line Parameters
/// -h 127.0.0.1 -p 1414 -c TEST.CHL -m MQWT1 -q TEST.Q1
///
/// </summary>
namespace MQTest51
{
   class MQTest51
   {
      private Hashtable inParms = null;
      private Hashtable qMgrProp = null;
      private System.String qManager;
      private System.String outputQName;

      /*
      * The constructor
      */
      public MQTest51()
         : base()
      {
      }

      /// <summary> Make sure the required parameters are present.</summary>
      /// <returns> true/false
      /// </returns>
      private bool allParamsPresent()
      {
         bool b = inParms.ContainsKey("-h") && inParms.ContainsKey("-p") &&
                  inParms.ContainsKey("-c") && inParms.ContainsKey("-m") &&
                  inParms.ContainsKey("-q");
         if (b)
         {
            try
            {
               System.Int32.Parse((System.String)inParms["-p"]);
            }
            catch (System.FormatException e)
            {
               b = false;
            }
         }

         return b;
      }

      /// <summary> Extract the command-line parameters and initialize the MQ variables.</summary>
      /// <param name="args">
      /// </param>
      /// <throws>  IllegalArgumentException </throws>
      private void init(System.String[] args)
      {
         inParms = Hashtable.Synchronized(new Hashtable());
         if (args.Length > 0 && (args.Length % 2) == 0)
         {
            for (int i = 0; i < args.Length; i += 2)
            {
               inParms[args[i]] = args[i + 1];
            }
         }
         else
         {
            throw new System.ArgumentException();
         }

         if (allParamsPresent())
         {
            qManager = ((System.String)inParms["-m"]);
            outputQName = ((System.String)inParms["-q"]);

            qMgrProp = new Hashtable();

            qMgrProp.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);

            qMgrProp.Add(MQC.HOST_NAME_PROPERTY, ((System.String)inParms["-h"]));
            qMgrProp.Add(MQC.CHANNEL_PROPERTY, ((System.String)inParms["-c"]));

            try
            {
               qMgrProp.Add(MQC.PORT_PROPERTY, System.Int32.Parse((System.String)inParms["-p"]));
            }
            catch (System.FormatException e)
            {
               qMgrProp.Add(MQC.PORT_PROPERTY, 1414);
            }

            if (inParms.ContainsKey("-u"))
               qMgrProp.Add(MQC.USER_ID_PROPERTY, ((System.String)inParms["-u"]));

            if (inParms.ContainsKey("-x"))
               qMgrProp.Add(MQC.PASSWORD_PROPERTY, ((System.String)inParms["-x"]));

            if ( (inParms.ContainsKey("-u")) && (inParms.ContainsKey("-x")) )
               qMgrProp.Add(MQC.USE_MQCSP_AUTHENTICATION_PROPERTY, true);
         }
         else
         {
            throw new System.ArgumentException();
         }
      }

      /// <summary> Connect, open queue, write a message, close queue and disconnect.
      ///
      /// </summary>
      /// <throws>  MQException </throws>
      private void testSend()
      {
         MQQueueManager qMgr = null;
         MQQueue outQ = null;
         System.String line = "This is a test message embedded in the MQTest51 program.";
         int openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING;
         MQPutMessageOptions pmo = new MQPutMessageOptions();

         try
         {
            qMgr = new MQQueueManager(qManager, qMgrProp);
            System.Console.Out.WriteLine("MQTest51 successfully connected to " + qManager);

            outQ = qMgr.AccessQueue(outputQName, openOptions);
            System.Console.Out.WriteLine("MQTest51 successfully opened " + outputQName);

            // Define a simple MQ message, and write some text in UTF format..
            MQMessage sendmsg = new MQMessage();
            sendmsg.Format = MQC.MQFMT_STRING;
            sendmsg.MessageType = MQC.MQMT_DATAGRAM;
            sendmsg.MessageId = MQC.MQMI_NONE;
            sendmsg.CorrelationId = MQC.MQCI_NONE;
            sendmsg.WriteString(line);

            // put the message on the outQ
            outQ.Put(sendmsg, pmo);
            System.Console.Out.WriteLine("Message Data>>>" + line);
         }
         catch (MQException mqex)
         {
            System.Console.Out.WriteLine("MQTest51 CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
         }
         catch (System.IO.IOException ioex)
         {
            System.Console.Out.WriteLine("MQTest51 ioex=" + ioex);
         }
         finally
         {
            try
            {
                if (outQ != null)
                {
                    outQ.Close();
                    System.Console.Out.WriteLine("MQTest51 closed: " + outputQName);
                }
            }
            catch (MQException mqex)
            {
                System.Console.Out.WriteLine("MQTest51 CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
            }

            try
            {
                if (qMgr != null)
                {
                    qMgr.Disconnect();
                    System.Console.Out.WriteLine("MQTest51 disconnected from " + qManager);
                }
            }
            catch (MQException mqex)
            {
                System.Console.Out.WriteLine("MQTest51 CC=" + mqex.CompletionCode + " : RC=" + mqex.ReasonCode);
            }
         }
      }

      /// <summary> main line</summary>
      /// <param name="args">
      /// </param>
      //        [STAThread]
      public static void Main(System.String[] args)
      {
         MQTest51 write = new MQTest51();

         try
         {
            write.init(args);
            write.testSend();
         }
         catch (System.ArgumentException e)
         {
            System.Console.Out.WriteLine("Usage: MQTest51 -h host -p port -c channel -m QueueManagerName -q QueueName [-u userID] [-x passwd]");
            System.Environment.Exit(1);
         }
         catch (MQException e)
         {
            System.Console.Out.WriteLine(e);
            System.Environment.Exit(1);
         }

         System.Environment.Exit(0);
      }
   }
}


标签: ibm-mq