.NET 使用 WMQ 连接Queue 发送 message 实例

  1. 首先得下载客户端,没有客户端无法发送message. 安装好之后长这样 我装的是7.5

安装目录如下 tools/dotnet 目录中有演示的demo

  1. .Net 连接MQ必须引用bin目录中的 amqmdnet.dll 因为他是创建Queuemanager 的核心库,

项目中引用using IBM.WMQ; 才不会报错. 引用amqmdnet 之后如果连接报错 可能缺少amqmdxcs.dll 则需要添加amqmdxcs.dll 在安装目录/bin64 目录可以找到该文件,我因为安装完就客户端,自动会将MQ所需的环境变量配置好,每次build完成后目录会多出来amqmdxcs.dll 文件,所以不需要再次引入

也可以Nuget安装IbmMqClient 包

  1. 下面是演示代码:
cs 复制代码
using System;
using System.Collections;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Threading;
using IBM.WMQ;

class MQInteractiveSender
{
    static readonly string QManager = ConfigurationManager.AppSettings["QManager"];
    static readonly string HostName = ConfigurationManager.AppSettings["HostName"];

    static void Main()
    {
        Console.Title = "IBM MQ 交互式消息发送器 (带配置默认值)";
        Console.WriteLine("=== MQ 交互式消息发送程序 ===");
        Console.WriteLine("注意:直接按Enter将使用配置的默认值\n");

        while (true)
        {
            try
            {
                // 从配置读取默认值
                var defaults = new
                {
                    Channel = ConfigurationManager.AppSettings["DefaultChannel"],
                    Queue = ConfigurationManager.AppSettings["DefaultQueue"],
                    XmlDir = ConfigurationManager.AppSettings["DefaultXmlDir"],
                    XmlFile = ConfigurationManager.AppSettings["DefaultXmlFile"],
                    Count = int.Parse(ConfigurationManager.AppSettings["DefaultMessageCount"]),
                    Interval = int.Parse(ConfigurationManager.AppSettings["DefaultIntervalMs"])
                };

                // 用户输入参数(带配置默认值)
                Console.WriteLine("\n=== 新消息批次 ===");
                string channel = ReadInput("通道名称", defaults.Channel);
                string queueName = ReadInput("队列名称", defaults.Queue, true);
                string xmlDir = ReadInput("XML文件夹", defaults.XmlDir);
                string xmlFile = ReadInput("XML文件名", defaults.XmlFile);
                string xmlPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, xmlDir, xmlFile);
                int messageCount = ReadIntInput("发送次数", defaults.Count);
                int intervalMs = ReadIntInput("发送间隔(毫秒)", defaults.Interval);

                // 验证文件
                if (!File.Exists(xmlPath))
                {
                    Console.WriteLine($"错误:XML文件不存在 - {xmlPath}");
                    if (!AskYesNo("是否继续?(y/n)", true)) break;
                    continue;
                }

                // 发送消息
                SendMessages(channel, queueName, xmlPath, messageCount, intervalMs);

                // 询问是否继续
                if (!AskYesNo("继续发送新消息?(y/n)", true)) break;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发生错误: {ex.Message}");
                if (!AskYesNo("是否继续?(y/n)", true)) break;
            }
        }
        Console.WriteLine("\n程序已退出");
    }

    static void SendMessages(string channel, string queueName, string xmlPath, int count, int intervalMs)
    {
        Hashtable mqProps = new Hashtable
        {
            [MQC.HOST_NAME_PROPERTY] = HostName,
            [MQC.CHANNEL_PROPERTY] = channel,
            [MQC.TRANSPORT_PROPERTY] = MQC.TRANSPORT_MQSERIES_CLIENT
        };

        string xmlContent = File.ReadAllText(xmlPath);
        string compressedXml = RemoveWhitespace(xmlContent);

        // 添加计时器
        Stopwatch stopwatch = new Stopwatch();
        long totalElapsedMs = 0;
        int successCount = 0;

        using (var qMgr = new MQQueueManager(QManager, mqProps))
        using (var queue = qMgr.AccessQueue(queueName, MQC.MQOO_OUTPUT))
        {
            for (int i = 0; i < count; i++)
            {
                try
                {
                    stopwatch.Restart();

                    var msg = new MQMessage();
                    msg.WriteString(compressedXml.Replace("{{SEQ}}", (i + 1).ToString()));
                    queue.Put(msg, new MQPutMessageOptions());

                    stopwatch.Stop();
                    totalElapsedMs += stopwatch.ElapsedMilliseconds;
                    successCount++;

                    Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 发送 {i + 1}/{count}" +
                        $" | 本次耗时: {stopwatch.ElapsedMilliseconds}ms" +
                        $" | 平均耗时: {totalElapsedMs / successCount}ms");

                    if (i < count - 1 && intervalMs > 0)
                        Thread.Sleep(intervalMs);
                }
                catch (MQException ex)
                {
                    stopwatch.Stop();
                    Console.WriteLine($"[错误] 发送失败: {ex.ReasonCode} - {ex.Message}");
                }
            }
        }

        // 打印最终统计
        PrintStatistics(successCount, count, totalElapsedMs, intervalMs);
    }

    static void PrintStatistics(int success, int total, long totalMs, int intervalMs)
    {
        Console.WriteLine("\n======== 发送统计 ========");
        Console.WriteLine($"成功发送: {success}/{total}");
        Console.WriteLine($"总耗时: {totalMs / 1000.0:F2}秒");

        if (success > 0)
        {
            Console.WriteLine($"平均每条耗时: {totalMs / success}ms");
            Console.WriteLine($"纯发送速率: {success / (totalMs / 1000.0):F2} 条/秒");

            if (intervalMs > 0)
            {
                double theoreticalMinTime = total * intervalMs / 1000.0;
                Console.WriteLine($"包含间隔的理论速率: {total / theoreticalMinTime:F2} 条/秒");
            }
        }

        Console.WriteLine("========================");
    }



    #region 输入辅助方法(带配置默认值支持)
    static string ReadInput(string prompt, string defaultValue, bool required = false)
    {
        Console.Write($"{prompt} [默认: {defaultValue}]: ");
        string input = Console.ReadLine().Trim();

        if (string.IsNullOrEmpty(input)) return defaultValue;
        return input;
    }

    static int ReadIntInput(string prompt, int defaultValue, int? minValue = null, int? maxValue = null)
    {
        while (true)
        {
            Console.Write($"{prompt} [默认: {defaultValue}]: ");
            string input = Console.ReadLine().Trim();

            if (string.IsNullOrEmpty(input)) return defaultValue;

            if (int.TryParse(input, out int result))
            {
                if (minValue.HasValue && result < minValue.Value)
                {
                    Console.WriteLine($"不能小于 {minValue.Value}!");
                    continue;
                }
                if (maxValue.HasValue && result > maxValue.Value)
                {
                    Console.WriteLine($"不能大于 {maxValue.Value}!");
                    continue;
                }
                return result;
            }
            Console.WriteLine("请输入有效整数!");
        }
    }

    static bool AskYesNo(string question, bool defaultYes)
    {
        string defaultText = defaultYes ? "y" : "n";
        Console.Write($"{question} [默认: {defaultText}]: ");
        string input = Console.ReadLine().Trim().ToLower();

        if (string.IsNullOrEmpty(input)) return defaultYes;
        return input.StartsWith("y");
    }

    static string RemoveWhitespace(string xml) =>
        System.Text.RegularExpressions.Regex.Replace(xml, @">\s+<", "><").Trim();
    #endregion
}
  1. 配置文件app.Config
XML 复制代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<appSettings>
		<!-- MQ 连接默认参数 -->
		<add key="DefaultChannel" value="SYSTEM.DEF.SVRCONN"/>
		<add key="DefaultQueue" value="QUEUE_B"/>
		<add key="DefaultXmlDir" value="Xml"/>
		<add key="DefaultXmlFile" value="message.xml"/>

		<!-- 发送设置默认参数 -->
		<add key="DefaultMessageCount" value="1"/>
		<add key="DefaultIntervalMs" value="100"/>

		<!-- 其他配置 -->
		<add key="QManager" value="QM"/>
		<add key="HostName" value="localhost"/>
	</appSettings>
</configuration>

IbmMqClient 代码片段 需要安装http://www.ikvm.net/ 并配置环境变量

cs 复制代码
    //配置MQ服务器连接参数
    MQEnvironment.hostname = HostName;
    MQEnvironment.port = Port;
    MQEnvironment.channel = ChannelName;
    //设置应用名称,方便服务器MQ 查看应用连接
    //MQEnvironment.properties.put(CommonConstants.USERID, "MQ Test By Java");
    mQQueueManager = new MQQueueManager(QmName);

if (mQQueueSend == null)
{
    //mQQueueSend = mQQueueManager.accessQueue(queueName, com.ibm.mq.constants.CMQC.MQOO_OUTPUT);
    mQQueueSend = mQQueueManager.accessQueue(queueName, MQC.MQOO_OUTPUT);
}
MQMessage message = new MQMessage();
message.writeUTF(body);
mQQueueSend.put(message);

5.在WMQ客户端队列管理器QA->,右键创建队列QUEUE_A, 默认端口1414

  1. 发送message 到QA channel 的队列的QUEUE_A

遇到的错误及总结:

1.如果无法创建队列或者queue,请将本地用户添加到qmq组

  1. WMQ 装完会默认配置java 环境变量,如果启动遇到failed to create jvm virtual machine 问题一定是原有的JAVA 环境变量 配置和WQM 冲突了或者顺序的原因,我本地是JAVA原有环境变量配置在了MQ_JAVA_LIB_PATH和MQ_JRE_PATH 之后导致,正确的是将JAVA_HOME 变量移动到MQ_开头相关的

3.如果启动代码报错2035 (07F3) (RC2035): MQRC_NOT_AUTHORIZED - IBM

则需要cmd 输入禁用授权规则

XML 复制代码
RUNMQSC QM

ALTER QMGR CHLAUTH(DISABLED)

或者在界面

相关推荐
闪电麦坤956 小时前
C#:base 关键字
开发语言·c#
mingupup7 小时前
C#连接小智服务器并将音频解码播放过程记录
c#
爱吃奶酪的松鼠丶10 小时前
.net GRPC服务搭建,跨进程调用。C#应用和Python应用之间的通信。
python·c#·.net
chushiyunen12 小时前
dom操作笔记、xml和document等
xml·java·笔记
whisperrr.12 小时前
【spring01】Spring 管理 Bean-IOC,基于 XML 配置 bean
xml·java·spring
勘察加熊人14 小时前
forms实现俄罗斯方块
c#
努力搬砖的咸鱼17 小时前
Qt中的数据解析--XML与JSON处理全攻略
xml·开发语言·qt·json
inxunoffice17 小时前
批量删除 txt/html/json/xml/csv 等文本文件中的重复行
xml
艾妮艾妮18 小时前
C语言常见3种排序
java·c语言·开发语言·c++·算法·c#·排序算法
小码编匠19 小时前
.NET 验证码生成神器基于 SkiaSharp 的高性能方案
后端·c#·.net