当前位置: 首页 > article >正文

C#使用MQTT(二):MQTT客户端

上一篇我们初步设计了MQTT服务端

C#使用MQTT(一):MQTT服务端-CSDN博客

这里我们设计客户端MQTT Client,接上一篇

新建Windows窗体FormMqttClient

窗体FormMqttClient设计如图:

窗体FormMqttClient设计器相关代码如下

文件FormMqttClient.Designer.cs


namespace CultureDemo
{
    partial class FormMqttClient
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.rtxtMessage = new System.Windows.Forms.RichTextBox();
            this.label8 = new System.Windows.Forms.Label();
            this.btnPublish = new System.Windows.Forms.Button();
            this.btnSubscribe = new System.Windows.Forms.Button();
            this.txtContent = new System.Windows.Forms.TextBox();
            this.label5 = new System.Windows.Forms.Label();
            this.txtTopicPublish = new System.Windows.Forms.TextBox();
            this.label6 = new System.Windows.Forms.Label();
            this.txtTopic = new System.Windows.Forms.TextBox();
            this.label7 = new System.Windows.Forms.Label();
            this.btnDisconnect = new System.Windows.Forms.Button();
            this.btnConnect = new System.Windows.Forms.Button();
            this.txtClientId = new System.Windows.Forms.TextBox();
            this.label4 = new System.Windows.Forms.Label();
            this.txtUpwd = new System.Windows.Forms.TextBox();
            this.label3 = new System.Windows.Forms.Label();
            this.txtUserName = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.txtPort = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.txtIP = new System.Windows.Forms.TextBox();
            this.lb = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // rtxtMessage
            // 
            this.rtxtMessage.Location = new System.Drawing.Point(239, 37);
            this.rtxtMessage.Name = "rtxtMessage";
            this.rtxtMessage.Size = new System.Drawing.Size(623, 411);
            this.rtxtMessage.TabIndex = 51;
            this.rtxtMessage.Text = "";
            // 
            // label8
            // 
            this.label8.AutoSize = true;
            this.label8.Location = new System.Drawing.Point(242, 18);
            this.label8.Name = "label8";
            this.label8.Size = new System.Drawing.Size(29, 12);
            this.label8.TabIndex = 50;
            this.label8.Text = "消息";
            // 
            // btnPublish
            // 
            this.btnPublish.Location = new System.Drawing.Point(117, 425);
            this.btnPublish.Name = "btnPublish";
            this.btnPublish.Size = new System.Drawing.Size(75, 23);
            this.btnPublish.TabIndex = 49;
            this.btnPublish.Text = "发布";
            this.btnPublish.UseVisualStyleBackColor = true;
            this.btnPublish.Click += new System.EventHandler(this.btnPublish_Click);
            // 
            // btnSubscribe
            // 
            this.btnSubscribe.Location = new System.Drawing.Point(117, 286);
            this.btnSubscribe.Name = "btnSubscribe";
            this.btnSubscribe.Size = new System.Drawing.Size(75, 23);
            this.btnSubscribe.TabIndex = 48;
            this.btnSubscribe.Text = "订阅";
            this.btnSubscribe.UseVisualStyleBackColor = true;
            this.btnSubscribe.Click += new System.EventHandler(this.btnSubscribe_Click);
            // 
            // txtContent
            // 
            this.txtContent.Location = new System.Drawing.Point(92, 377);
            this.txtContent.Name = "txtContent";
            this.txtContent.Size = new System.Drawing.Size(100, 21);
            this.txtContent.TabIndex = 47;
            // 
            // label5
            // 
            this.label5.AutoSize = true;
            this.label5.Location = new System.Drawing.Point(45, 380);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(29, 12);
            this.label5.TabIndex = 46;
            this.label5.Text = "内容";
            // 
            // txtTopicPublish
            // 
            this.txtTopicPublish.Location = new System.Drawing.Point(92, 341);
            this.txtTopicPublish.Name = "txtTopicPublish";
            this.txtTopicPublish.Size = new System.Drawing.Size(100, 21);
            this.txtTopicPublish.TabIndex = 45;
            // 
            // label6
            // 
            this.label6.AutoSize = true;
            this.label6.Location = new System.Drawing.Point(45, 344);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(29, 12);
            this.label6.TabIndex = 44;
            this.label6.Text = "主题";
            // 
            // txtTopic
            // 
            this.txtTopic.Location = new System.Drawing.Point(92, 248);
            this.txtTopic.Name = "txtTopic";
            this.txtTopic.Size = new System.Drawing.Size(100, 21);
            this.txtTopic.TabIndex = 43;
            // 
            // label7
            // 
            this.label7.AutoSize = true;
            this.label7.Location = new System.Drawing.Point(45, 251);
            this.label7.Name = "label7";
            this.label7.Size = new System.Drawing.Size(29, 12);
            this.label7.TabIndex = 42;
            this.label7.Text = "主题";
            // 
            // btnDisconnect
            // 
            this.btnDisconnect.Location = new System.Drawing.Point(130, 205);
            this.btnDisconnect.Name = "btnDisconnect";
            this.btnDisconnect.Size = new System.Drawing.Size(75, 23);
            this.btnDisconnect.TabIndex = 41;
            this.btnDisconnect.Text = "断开";
            this.btnDisconnect.UseVisualStyleBackColor = true;
            this.btnDisconnect.Click += new System.EventHandler(this.btnDisconnect_Click);
            // 
            // btnConnect
            // 
            this.btnConnect.Location = new System.Drawing.Point(36, 205);
            this.btnConnect.Name = "btnConnect";
            this.btnConnect.Size = new System.Drawing.Size(75, 23);
            this.btnConnect.TabIndex = 40;
            this.btnConnect.Text = "连接";
            this.btnConnect.UseVisualStyleBackColor = true;
            this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
            // 
            // txtClientId
            // 
            this.txtClientId.Location = new System.Drawing.Point(67, 164);
            this.txtClientId.Name = "txtClientId";
            this.txtClientId.Size = new System.Drawing.Size(134, 21);
            this.txtClientId.TabIndex = 39;
            this.txtClientId.Text = "snake";
            // 
            // label4
            // 
            this.label4.AutoSize = true;
            this.label4.Location = new System.Drawing.Point(20, 167);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(41, 12);
            this.label4.TabIndex = 38;
            this.label4.Text = "客户ID";
            // 
            // txtUpwd
            // 
            this.txtUpwd.Location = new System.Drawing.Point(67, 127);
            this.txtUpwd.Name = "txtUpwd";
            this.txtUpwd.Size = new System.Drawing.Size(134, 21);
            this.txtUpwd.TabIndex = 37;
            this.txtUpwd.Text = "1";
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(32, 130);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(29, 12);
            this.label3.TabIndex = 36;
            this.label3.Text = "密码";
            // 
            // txtUserName
            // 
            this.txtUserName.Location = new System.Drawing.Point(67, 100);
            this.txtUserName.Name = "txtUserName";
            this.txtUserName.Size = new System.Drawing.Size(134, 21);
            this.txtUserName.TabIndex = 35;
            this.txtUserName.Text = "a";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(32, 103);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(29, 12);
            this.label2.TabIndex = 34;
            this.label2.Text = "账号";
            // 
            // txtPort
            // 
            this.txtPort.Location = new System.Drawing.Point(67, 64);
            this.txtPort.Name = "txtPort";
            this.txtPort.Size = new System.Drawing.Size(134, 21);
            this.txtPort.TabIndex = 33;
            this.txtPort.Text = "12345";
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(32, 67);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(29, 12);
            this.label1.TabIndex = 32;
            this.label1.Text = "端口";
            // 
            // txtIP
            // 
            this.txtIP.Location = new System.Drawing.Point(67, 22);
            this.txtIP.Name = "txtIP";
            this.txtIP.Size = new System.Drawing.Size(134, 21);
            this.txtIP.TabIndex = 31;
            this.txtIP.Text = "127.0.0.1";
            // 
            // lb
            // 
            this.lb.AutoSize = true;
            this.lb.Location = new System.Drawing.Point(20, 25);
            this.lb.Name = "lb";
            this.lb.Size = new System.Drawing.Size(41, 12);
            this.lb.TabIndex = 30;
            this.lb.Text = "IP地址";
            // 
            // FormMqttClient
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(874, 525);
            this.Controls.Add(this.rtxtMessage);
            this.Controls.Add(this.label8);
            this.Controls.Add(this.btnPublish);
            this.Controls.Add(this.btnSubscribe);
            this.Controls.Add(this.txtContent);
            this.Controls.Add(this.label5);
            this.Controls.Add(this.txtTopicPublish);
            this.Controls.Add(this.label6);
            this.Controls.Add(this.txtTopic);
            this.Controls.Add(this.label7);
            this.Controls.Add(this.btnDisconnect);
            this.Controls.Add(this.btnConnect);
            this.Controls.Add(this.txtClientId);
            this.Controls.Add(this.label4);
            this.Controls.Add(this.txtUpwd);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.txtUserName);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.txtPort);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.txtIP);
            this.Controls.Add(this.lb);
            this.Name = "FormMqttClient";
            this.Text = "FormMqttClient";
            this.Load += new System.EventHandler(this.FormMqttClient_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.RichTextBox rtxtMessage;
        private System.Windows.Forms.Label label8;
        private System.Windows.Forms.Button btnPublish;
        private System.Windows.Forms.Button btnSubscribe;
        private System.Windows.Forms.TextBox txtContent;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.TextBox txtTopicPublish;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.TextBox txtTopic;
        private System.Windows.Forms.Label label7;
        private System.Windows.Forms.Button btnDisconnect;
        private System.Windows.Forms.Button btnConnect;
        private System.Windows.Forms.TextBox txtClientId;
        private System.Windows.Forms.Label label4;
        private System.Windows.Forms.TextBox txtUpwd;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.TextBox txtUserName;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox txtPort;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox txtIP;
        private System.Windows.Forms.Label lb;
    }
}

窗体FormMqttClient程序代码如下:客户端程序

文件FormMqttClient.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MQTTnet;
using MQTTnet.Client;

namespace CultureDemo
{
    public partial class FormMqttClient : Form
    {
        IMqttClient mqttClient;
        public FormMqttClient()
        {
            InitializeComponent();
            rtxtMessage.ReadOnly = true;
        }

        /// <summary>
        /// 打印相关消息
        /// </summary>
        /// <param name="contents"></param>
        private void DisplayMessage(string contents)
        {
            if (!this.IsHandleCreated)
            {
                return;
            }
            this.BeginInvoke(new Action(() =>
            {
                if (rtxtMessage.TextLength >= 40960)
                {
                    rtxtMessage.Clear();
                }
                rtxtMessage.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}->{contents}\n");
                rtxtMessage.ScrollToCaret();
            }));
        }

        private void FormMqttClient_Load(object sender, EventArgs e)
        {
            mqttClient = new MqttFactory().CreateMqttClient();
            mqttClient.ConnectedAsync += MqttClient_ConnectedAsync;
            mqttClient.DisconnectedAsync += MqttClient_DisconnectedAsync;
            mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync;
        }

        private Task MqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs e)
        {
            return Task.Run(new Action(() =>
            {
                string msg = e.ApplicationMessage.ConvertPayloadToString();
                DisplayMessage($"接收消息:{msg}\nQoS={e.ApplicationMessage.QualityOfServiceLevel}\n客户端={e.ClientId}\n主题:{e.ApplicationMessage.Topic}");
            }));
        }

        private Task MqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs e)
        {
            return Task.Run(new Action(async () =>
            {
                DisplayMessage($"已断开到MQTT服务端的连接.尝试重新连接");
                try
                {
                    await Task.Delay(3000);
                    //MqttClientOptions options = new MqttClientOptions();
                    //await mqttClient.ConnectAsync(options);
                    await mqttClient.ReconnectAsync();
                }
                catch (Exception ex)
                {
                    DisplayMessage($"重新连接服务器失败:{ex.Message}");
                }
            }));
        }

        private Task MqttClient_ConnectedAsync(MqttClientConnectedEventArgs e)
        {
            return Task.Run(new Action(() =>
            {
                DisplayMessage($"连接到MQTT服务端成功.{e.ConnectResult.AssignedClientIdentifier}");
            }));
        }

        private async void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                MqttClientOptionsBuilder mqttClientOptionBuild = new MqttClientOptionsBuilder()
                 .WithClientId(this.txtClientId.Text)
                 .WithTcpServer(this.txtIP.Text, int.Parse(this.txtPort.Text))
                 .WithCredentials(this.txtUserName.Text, this.txtUpwd.Text);
                MqttClientOptions options = mqttClientOptionBuild.Build();
                //开启
                await mqttClient.ConnectAsync(options);
            }
            catch (Exception ex) 
            {
                DisplayMessage($"连接服务端时出现异常:{ex.Message}");
            }
        }

        private async void btnDisconnect_Click(object sender, EventArgs e)
        {
            if (mqttClient != null)
            {
                if (mqttClient.IsConnected)
                {
                    await mqttClient.DisconnectAsync();
                }
                mqttClient.Dispose();
            }
        }

        private async void btnSubscribe_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(this.txtTopic.Text))
            {
                DisplayMessage(">>> 请输入主题");
                return;
            }
            //在 MQTT 中有三种 QoS 级别: QuanlityOfService
            //At most once(0) 最多一次
            //At least once(1) 至少一次
            //Exactly once(2) 恰好一次
            MqttClientSubscribeOptionsBuilder subscribeOptionsBuilder = new MqttClientSubscribeOptionsBuilder();
            MqttClientSubscribeOptions subscribeOption = subscribeOptionsBuilder.WithTopicFilter(this.txtTopic.Text).Build();
            await mqttClient.SubscribeAsync(subscribeOption);
            DisplayMessage($">>> 成功订阅主题【{txtTopic.Text}】");
        }

        private async void btnPublish_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(this.txtTopicPublish.Text))
            {
                DisplayMessage(">>> 请输入主题");
                return;
            }
            MqttClientPublishResult result = await mqttClient.PublishStringAsync(
                this.txtTopicPublish.Text,
                this.txtContent.Text,
                MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);//恰好一次, QoS 级别1   
            DisplayMessage($"发布消息--主题:{this.txtTopicPublish.Text},消息:{this.txtContent.Text},结果: {result.ReasonCode}");
        }
    }
}

为了一个应用程序可以作为客户端和服务端,我们在Program.cs增加切换开关

选择作为MQTT服务端和MQTT客户端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CultureDemo
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            DialogResult dialog = MessageBox.Show("请选择程序作为MQTT服务端还是客户端,选择\"是\"作为服务端,选择\"否\"作为客户端", "是否MQTT服务端", MessageBoxButtons.YesNo);
            if (dialog == DialogResult.Yes)
            {
                Application.Run(new FormMqttServer());
            }
            else 
            {
                Application.Run(new FormMqttClient());
            }
        }
    }
}

程序运行如图:

运行客户端与服务端通信


http://www.kler.cn/a/290892.html

相关文章:

  • 深入了解蓝牙Profile类型与设备的对应关系
  • PostgreSQL 的历史
  • 代码随想录 day52 第十一章 图论part03
  • GM_T 0039《密码模块安全检测要求》题目
  • Idean 处理一个项目引用另外一个项目jar 但jar版本低的问题
  • vue2使用render,js中写html
  • [数据集][目标检测]街头摊贩识别检测数据集VOC+YOLO格式758张1类别
  • axure9勾选多个删除,弹框显示多个中继器编号
  • sed 命令及实战案例
  • C++ 学习 2024.9.3
  • GS-SLAM论文阅读笔记--GSFusion
  • windows C++ 虚拟内存的按需调拨
  • 利用Python解析json生成PPT、xmind思维导图教程
  • 144-Linux权限维持OpenSSHPAM后门SSH软链接公私钥登录
  • 包的相关知识
  • echarts--Y轴名称超宽换行显示行高问题处理
  • LaTeX各符号表示方式(持续更新~)
  • 嵌入式学习(双向链表)
  • OPenCV结构分析与形状描述符(1)近似多边形轮廓顶点的函数approxPolyDP()的使用
  • 大数据-117 - Flink DataStream Sink 案例:写出到MySQL、写出到Kafka
  • flume 使用 exec 采集容器日志,转储磁盘
  • C++奇迹之旅:深度解析list的模拟实现
  • 【网络安全】服务基础第一阶段——第十一节:Windows系统管理基础----PKI技术与应用
  • c# json使用
  • 判断一个数是不是2的次方数
  • 碰撞检测 | 详解矩形AABB与OBB碰撞检测算法(附ROS C++可视化)