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

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();}#endregionprivate 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());}}}
}

程序运行如图:

运行客户端与服务端通信

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【JAVA】Tomcat性能优化、安全配置、资源控制以及运行模式超详细
  • Self Refine技术测评:利用Self Refine提高LLM的生成质量
  • 微信小程序:navigateTo跳转无效
  • 学习node.js十三,文件的上传于下载
  • D 咖智能饮品机器人:科技与美味共舞,奏响饮品新乐章
  • SQL server 的异常处理 一个SQL异常 如何不影响其他SQL执行
  • UEC++学习(十七)利用SceneCaptureComponent2d进行截图
  • 使用python对股票市场进行数据挖掘的书籍资料有哪些
  • 基于Python的自然语言处理系列(3):GloVe
  • “声”临其境:iKF Ultra 降噪耳机,音乐与静谧的完美融合
  • 2024国赛数学建模C题论文:基于优化模型的农作物的种植策略
  • 安防监控/视频汇聚平台EasyCVR无法启动并报错“error while loading shared libraries”,如何解决?
  • Ribbon快速了解
  • 如何在5个步骤中编写更好的ChatGPT提示
  • React Native防止重复点击
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • C# 免费离线人脸识别 2.0 Demo
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • co.js - 让异步代码同步化
  • ES6系统学习----从Apollo Client看解构赋值
  • FastReport在线报表设计器工作原理
  • HTTP中GET与POST的区别 99%的错误认识
  • JavaScript实现分页效果
  • Laravel核心解读--Facades
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • nodejs调试方法
  • PhantomJS 安装
  • SQLServer之索引简介
  • 代理模式
  • 基于Android乐音识别(2)
  • 蓝海存储开关机注意事项总结
  • 前端之React实战:创建跨平台的项目架构
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 移动端解决方案学习记录
  • 交换综合实验一
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​zookeeper集群配置与启动
  • # wps必须要登录激活才能使用吗?
  • #FPGA(基础知识)
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • (6)添加vue-cookie
  • (C语言)逆序输出字符串
  • (Git) gitignore基础使用
  • (pytorch进阶之路)扩散概率模型
  • (ros//EnvironmentVariables)ros环境变量
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (二刷)代码随想录第15天|层序遍历 226.翻转二叉树 101.对称二叉树2
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (四)c52学习之旅-流水LED灯
  • (四)Linux Shell编程——输入输出重定向
  • (五)IO流之ByteArrayInput/OutputStream