我期待实现一个有点智能的MQ通信模块,该模块应该能够容忍网络连接中断。基本上,如果连接丢失,它应该尝试每5秒重新连接一次。
问题如下。我使用以下代码进行阅读:
queueMessage = new MQMessage();
queueMessage.Format = MQC.MQFMT_STRING;
queueGetMessageOptions = new MQGetMessageOptions();
queueGetMessageOptions.Options = MQC.MQGMO_SYNCPOINT + MQC.MQGMO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING;
queueGetMessageOptions.WaitInterval = 50;
producerQueue.Get(queueMessage, queueGetMessageOptions);
msg = queueMessage.ReadBytes(queueMessage.MessageLength);
(当然我之前成功连接到队列管理员等)
我遇到了以下问题:当此例程运行时,但在.Get
没有连接时,代码只会挂起并保留在.Get
中。
我使用一个计时器来查看是否有超时(理论上即使这不是必要的,是吗?)并且在超时时我尝试重新连接。但是当超时到期时,我仍然看到队列管理器报告它已连接,而它显然没有(没有物理连接存在)。自从我使用SYNCPOINT以来,这个问题就出现了,我在写作期间切断连接时遇到了同样的问题,或者在这种情况下,我尝试在队列管理器上强制断开连接。所以请帮忙,我应该使用哪些设置来避免陷入Get
和Put
,而是抛出MQException
或可控制的东西?
谢谢!
更新:我使用以下代码连接到QueueManager。
Hashtable props = new Hashtable();
props.Add(MQC.HOST_NAME_PROPERTY, Host);
props.Add(MQC.PORT_PROPERTY, Port);
props.Add(MQC.CHANNEL_PROPERTY, ChannelInfo);
if(User!="") props.Add(MQC.USER_ID_PROPERTY, User);
if(Password!="") props.Add(MQC.PASSWORD_PROPERTY, Password);
props.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
queueManager = new MQQueueManager(QueueManagerName, props);
producerQueue = queueManager.AccessQueue(
ProducerQueueName,
MQC.MQOO_INPUT_AS_Q_DEF // open queue for input
+ MQC.MQOO_FAIL_IF_QUIESCING); // but not if MQM stopping
consumerQueue = queueManager.AccessQueue(
ConsumerQueueName,
MQC.MQOO_OUTPUT + MQC.MQOO_BROWSE + MQC.MQOO_INPUT_AS_Q_DEF // open queue for output
+ MQC.MQOO_FAIL_IF_QUIESCING); // but not if MQM stopping
毋庸置疑,通常代码运行良好。读/写,连接/断开工作原理,我只需要弄清楚当前的问题。 谢谢!
答案 0 :(得分:2)
您使用的是哪个版本的MQ?要使自动重新连接正常工作,队列管理器至少需要在MQ v701,MQ .NET客户端需要是MQ v7.1级别。
假设您使用的是MQ v7.1 .NET客户端,则需要在连接创建期间指定重新连接选项。您需要通过添加以下内容来启用重新连接:
props.Add(MQC.CONNECT_OPTIONS_PROPERTY, MQC.MQCNO_RECONNECT);
也可以从mqclient.ini文件启用/禁用重新连接。
但令人惊讶的是,当没有网络连接时,Get / Put会挂起。希望您没有连接与应用程序在同一台机器上运行的队列管理器。无需设置任何计时器或类似的东西。您可以发出MQ调用,如果连接有任何问题,将抛出异常。
更新
我认为你指的是IsConnected
类的MQQueueManager
属性。文档说明了这个属性的值:“如果为true,则表明已经建立了与队列管理器的连接,并且不知道是否已被破坏。对IsConnected的任何调用都不会主动尝试访问队列管理器,因此有可能物理连接可能会中断,但IsConnected仍然可以返回true。只有在队列管理器上执行活动(例如,发送消息,获取消息)时,才会更新IsConnected状态。
如果为false,则表示尚未建立与队列管理器的连接,或者已断开连接或已断开连接。“
正如您所看到的,True
值并不意味着连接仍然是ON。我的建议是调用一个方法,Put / Get并处理抛出的任何异常。
Put / Get / Disconnect呼叫挂起似乎是个问题。我的建议是与IBM一起提出PMR。