Ibm mq 在XMS.NET中为每个连接配置单独的CCDT文件

Ibm mq 在XMS.NET中为每个连接配置单独的CCDT文件,ibm-mq,xms,Ibm Mq,Xms,作为合作伙伴的要求,我们必须在不同的端口上建立MQ连接。要求为每个端口配置独立的CCDT文件,因为。所有连接都在一个客户端应用程序(一个进程)上进行 因为我们的客户端应用程序是一个进程,所以我无法为每个端口分别配置以下环境变量 如何设置环境变量以配置客户端通道定义(这是.NET C#): Environment.SetEnvironmentVariable("MQCHLLIB", @"C:\ProgramData\IBM\MQ"); Environment.Set

作为合作伙伴的要求,我们必须在不同的端口上建立MQ连接。要求为每个端口配置独立的CCDT文件,因为。所有连接都在一个客户端应用程序(一个
进程
)上进行

因为我们的客户端应用程序是一个
进程
,所以我无法为每个端口分别配置以下环境变量

如何设置环境变量以配置客户端通道定义(这是.NET C#):

        Environment.SetEnvironmentVariable("MQCHLLIB", @"C:\ProgramData\IBM\MQ");
        Environment.SetEnvironmentVariable("MQCHLTAB", "AMQCLCHL<PORT>.TAB");
Environment.SetEnvironmentVariable(“MQCHLLIB”,@“C:\ProgramData\IBM\MQ”);
SetEnvironmentVariable(“MQCHLTAB”、“AMQCLCHL.TAB”);
我们的问题;我们必须在连接级别上设置这些环境变量,而不是在流程或全局级别上。有什么建议吗

以下更新来自评论和聊天中收集的信息:

  • 需求是使用XMS.NET配置头和消息压缩
  • 根据IBM对IBM社区论坛帖子的回答,“XMS.NET只能使用CCDT进行压缩
  • CCDT条目具有
    QMNAME(*)
  • CCDT条目之间的差异仅在于
    端口

  • 您是说,一旦启动应用程序(进程),它将在一次执行中与不同的队列管理器连接并断开连接?如果是这样,那么设置环境变量,然后动态更改它们将不起作用

    更好的方法是使用一个包含4个部分的INI文件—每个端口1个。让您的应用程序从INI文件加载特定的部分,用这些特定的值创建一个哈希表,并将哈希表传递给MQQueueManager类

    有关读取INI文件的更多信息,请参阅:

    我会将INI文件的1414部分设置为:

    [Port1414]
    mq.qmname=MQA1
    mq.channel=TEST.CHL
    mq.hostname=10.10.10.10
    mq.port=1414
    mq.userid=MyUserId
    mq.inputq=SOME.INPUT.QUEUE
    mq.outputq=SOME.OUTPUT.QUEUE
    
    [Port1415]
    mq.qmname=MQA1
    mq.channel=TEST.CHL
    mq.hostname=10.10.10.10
    mq.port=1415
    mq.userid=MyUserId
    mq.inputq=SOME.INPUT.QUEUE2
    mq.outputq=SOME.OUTPUT.QUEUE2
    
    对于INI文件的1415部分,如下所示:

    [Port1414]
    mq.qmname=MQA1
    mq.channel=TEST.CHL
    mq.hostname=10.10.10.10
    mq.port=1414
    mq.userid=MyUserId
    mq.inputq=SOME.INPUT.QUEUE
    mq.outputq=SOME.OUTPUT.QUEUE
    
    [Port1415]
    mq.qmname=MQA1
    mq.channel=TEST.CHL
    mq.hostname=10.10.10.10
    mq.port=1415
    mq.userid=MyUserId
    mq.inputq=SOME.INPUT.QUEUE2
    mq.outputq=SOME.OUTPUT.QUEUE2
    
    1415和1416也一样

    读取INI文件的特定部分后,您将执行以下操作:

    Hashtable qMgrProp = new Hashtable();
    qMgrProp.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
    qMgrProp.Add(MQC.CHANNEL_PROPERTY, channelName);
    qMgrProp.Add(MQC.HOST_NAME_PROPERTY, hostname);
    qMgrProp.Add(MQC.PORT_PROPERTY, 1414);
    qMgrProp.Add(MQC.USER_ID_PROPERTY, userId);
    
    MQQueueManager qMgr = new MQQueueManager(qManager, qMgrProp);
    

    您是说,一旦启动应用程序(进程),它将在一次执行中与不同的队列管理器连接并断开连接?如果是这样,那么设置环境变量,然后动态更改它们将不起作用

    更好的方法是使用一个包含4个部分的INI文件—每个端口1个。让您的应用程序从INI文件加载特定的部分,用这些特定的值创建一个哈希表,并将哈希表传递给MQQueueManager类

    有关读取INI文件的更多信息,请参阅:

    我会将INI文件的1414部分设置为:

    [Port1414]
    mq.qmname=MQA1
    mq.channel=TEST.CHL
    mq.hostname=10.10.10.10
    mq.port=1414
    mq.userid=MyUserId
    mq.inputq=SOME.INPUT.QUEUE
    mq.outputq=SOME.OUTPUT.QUEUE
    
    [Port1415]
    mq.qmname=MQA1
    mq.channel=TEST.CHL
    mq.hostname=10.10.10.10
    mq.port=1415
    mq.userid=MyUserId
    mq.inputq=SOME.INPUT.QUEUE2
    mq.outputq=SOME.OUTPUT.QUEUE2
    
    对于INI文件的1415部分,如下所示:

    [Port1414]
    mq.qmname=MQA1
    mq.channel=TEST.CHL
    mq.hostname=10.10.10.10
    mq.port=1414
    mq.userid=MyUserId
    mq.inputq=SOME.INPUT.QUEUE
    mq.outputq=SOME.OUTPUT.QUEUE
    
    [Port1415]
    mq.qmname=MQA1
    mq.channel=TEST.CHL
    mq.hostname=10.10.10.10
    mq.port=1415
    mq.userid=MyUserId
    mq.inputq=SOME.INPUT.QUEUE2
    mq.outputq=SOME.OUTPUT.QUEUE2
    
    1415和1416也一样

    读取INI文件的特定部分后,您将执行以下操作:

    Hashtable qMgrProp = new Hashtable();
    qMgrProp.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
    qMgrProp.Add(MQC.CHANNEL_PROPERTY, channelName);
    qMgrProp.Add(MQC.HOST_NAME_PROPERTY, hostname);
    qMgrProp.Add(MQC.PORT_PROPERTY, 1414);
    qMgrProp.Add(MQC.USER_ID_PROPERTY, userId);
    
    MQQueueManager qMgr = new MQQueueManager(qManager, qMgrProp);
    
    选项1(如果可行,这似乎更简单,因为您不需要使用CCDT,因为它是以前唯一已知的指定压缩选项的方法):

    基于JMS和XMS的文档组合,我认为以下内容可能会起作用,请尝试一下,如果这不起作用,那么我将从我的答案中删除它,如果它起作用,那么我将使用指向混合文档的链接进行更新

    var factory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
    var cf = factory.CreateConnectionFactory();
    cf.SetStringProperty(XMSC.WMQ_HOST_NAME, host);
    cf.SetIntProperty(XMSC.WMQ_PORT, port);
    cf.SetStringProperty(XMSC.WMQ_CHANNEL, channel);
    //empty string "" or "*" would work equally well for XMSC.WMQ_QUEUE_MANAGER to accept any queue manager name
    cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "");
    cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED);
    cf.SetStringProperty(XMSC.WMQ_HEADER_COMP, "SYSTEM NONE");
    cf.SetStringProperty(XMSC.WMQ_MSG_COMP, "ZLIBFAST ZLIBHIGH RLE NONE");
    connection = cf.CreateConnection();
    

    选项2直接指定XMSFactoryFactory的CCDT位置,不依赖环境变量:

    创建CF时直接链接到CCDT,而不是使用环境变量

    var factory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
    var cf = factory.CreateConnectionFactory();
    cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED);
    cf.SetStringProperty(XMSC.WMQ_CCDTURL, @"file://C:\ProgramData\IBM\MQ\AMQCLCHL<PORT>.TAB";
    cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "*");
    connection = cf.CreateConnection();
    
    var factory=XMSFactoryFactory.GetInstance(XMSC.CT\u WMQ);
    var cf=factory.CreateConnectionFactory();
    cf.SetIntProperty(XMSC.WMQ_连接_模式,XMSC.WMQ_CM_客户端_非托管);
    cf.SetStringProperty(XMSC.WMQ_CCDTURL,@“file://C:\ProgramData\IBM\MQ\AMQCLCHL.TAB”;
    cf.SetStringProperty(XMSC.WMQ_队列管理器,“*”);
    connection=cf.CreateConnection();
    
    选项1(如果可行,这似乎更简单,因为您不需要使用CCDT,因为它是以前唯一已知的指定压缩选项的方法):

    基于JMS和XMS的文档组合,我认为以下内容可能会起作用,请尝试一下,如果这不起作用,那么我将从我的答案中删除它,如果它起作用,那么我将使用指向混合文档的链接进行更新

    var factory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
    var cf = factory.CreateConnectionFactory();
    cf.SetStringProperty(XMSC.WMQ_HOST_NAME, host);
    cf.SetIntProperty(XMSC.WMQ_PORT, port);
    cf.SetStringProperty(XMSC.WMQ_CHANNEL, channel);
    //empty string "" or "*" would work equally well for XMSC.WMQ_QUEUE_MANAGER to accept any queue manager name
    cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "");
    cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED);
    cf.SetStringProperty(XMSC.WMQ_HEADER_COMP, "SYSTEM NONE");
    cf.SetStringProperty(XMSC.WMQ_MSG_COMP, "ZLIBFAST ZLIBHIGH RLE NONE");
    connection = cf.CreateConnection();
    

    选项2直接指定XMSFactoryFactory的CCDT位置,不依赖环境变量:

    创建CF时直接链接到CCDT,而不是使用环境变量

    var factory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
    var cf = factory.CreateConnectionFactory();
    cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED);
    cf.SetStringProperty(XMSC.WMQ_CCDTURL, @"file://C:\ProgramData\IBM\MQ\AMQCLCHL<PORT>.TAB";
    cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "*");
    connection = cf.CreateConnection();
    
    var factory=XMSFactoryFactory.GetInstance(XMSC.CT\u WMQ);
    var cf=factory.CreateConnectionFactory();
    cf.SetIntProperty(XMSC.WMQ_连接_模式,XMSC.WMQ_CM_客户端_非托管);
    cf.SetStringProperty(XMSC.WMQ_CCDTURL,@“file://C:\ProgramData\IBM\MQ\AMQCLCHL.TAB”;
    cf.SetStringProperty(XMSC.WMQ_队列管理器,“*”);
    connection=cf.CreateConnection();
    
    选项:1.在CCDT中指定的任何内容都应该能够直接在程序中指定。2.您可以从绑定文件中提取JNDI信息。每个CF可以指向不同的CCDT。3.使用ENV变量而不是您的CCDT,使用
    mqclient.ini
    指向CCDT。MQ将首先在c中查找ini当前工作目录,在每次连接之前更改为端口指定的目录,因为您是多线程的,这将有与设置ENV类似的问题,只要您可以实现锁定,使ENV或ini一次只能连接一个线程。4.转储所有单个CCDT文件的内容并创建单个组合的CCDT。a只要
    QMNAME
    CHANNEL
    名称对每个连接都是唯一的,这可能是最简单的方法了。@但是我们的合作伙伴明确表示要为每个连接使用单独的CCDT文件。下面是一个报价:“应用程序不能依赖CCDT来平衡与队列管理器的连接,因为CCDT不能保证与所有队列管理器建立连接