C# 基于MQTT创建客户端的可靠数据传输

news2025/1/17 3:44:18

C# 基于MQTT创建客户端的可靠数据传输

  • 引言
  • MQTT简介
  • C# MQTT库引用
  • 代码和描述
    • 1、 代码
    • 2、 描述

引言

MQTT是tcpip的应用层协议,这里我们简单介绍一下MQTT的基本概念,并用C# 描述客户端的订阅和发布。

MQTT简介

  • MQTT(Message Queuing Telemetry Transport)即 消息队列遥测传输,是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它也是工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议。

  • MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

  • 通过MQTT协议,目前已经扩展出了数十个MQTT服务器端程序,可以通过PHP,JAVA,Python,C,C#等系统语言来向MQTT发送相关消息。

  • MQTT 服务器是发布-订阅架构的转发中心,它可以非常简单地在Internet 服务器上实现。服务器分发消息,因此是推送者,客户端可以发布消息(发送方)、订阅消息(接收方)或两者兼而有之。客户端(也称为节点)是一种智能设备,如微控制器或具有 TCP/IP 堆栈和实现 MQTT 协议的软件的计算机。
    在这里插入图片描述

  • QoS(Quality of Service levels)服务质量是 MQTT 的一个重要特性。当我们使用时,连接已经在一定程度上是不是面向连接的。MQTT 在这里帮助避免信息丢失及其服务质量水平。 服务质量水平包括三个等级。

    1. AtMostOnce ——最多一次
    2. AtLeastOnce ——至少一次
    3. ExactlyOnce ——恰好一次,这个服务质量可以确保数据准确的发送到订阅端。

C# MQTT库引用

这里我使用是VS2022,在工具中的netGet包管理器中打开“管理解决方案包“,搜索MQTTnet,找到对应的包。这里注意要选择自己合适的版本!注意要选择自己合适的版本!注意要选择自己合适的版本!重要的话说3遍。我在win10环境下使用的VS2022,验证了多次才发现4.1.2.350是合适的。如下图所示。
在这里插入图片描述

代码和描述

1、 代码

using System;
using System.Collections.Generic; 
using System.Threading.Tasks; 
using MQTTnet;
using MQTTnet.Client; 
using MQTTnet.Protocol;
using MQTTnet.Server;

namespace WriteSN
{
  internal class Mqtt
  {
      public static byte[] Mqtt_Message_Received_Str = new byte[] { };
  	//构造函数
      public Mqtt()
      {
         //初始化全局变量
          Mqtt_Message_Received_Str = new byte[] { };
      }

      /// <summary>
      ///  发布和订阅MQTT专用主题授权获取数据
      /// </summary>
      /// <param name="Data">发布传输字符串</param>
      /// <returns></returns>
      public async Task MQTT_Client_Handle(string Data)
      {
  		//服务端地址
  		string broker = "broker.emqx.io";
  		//端口·
  		int port = 8090;
  		//客户端ID
  		string clientId = Guid.NewGuid().ToString();
  		//订阅和发布的主题
  		string  req_topic = "trace_id_req";//发
  		string  rsp_topic = "trace_id_rsp";//收 
  		//用户和密码
  		string username = "";//"admin";
  		string password = "";//public";
  		
  		// Create a MQTT client factory 创建客户端代理
  		var factory = new MqttFactory();
  		
  		// Create a MQTT client instance 创建客户端实例
  		var mqttClient = factory.CreateMqttClient();
  		
          // Create MQTT client options 为连接服务器创建客户端选项
          var options = new MqttClientOptionsBuilder().
              .WithTcpServer(broker, port) // MQTT broker address and port
              .WithCredentials(username, password) // Set username and password
              .WithClientId(clientId).WithWillQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce)//QOS=2
              .WithCleanSession()
              .Build();
          // Connect to MQTT broker //连接代理服务器
          var connectResult = await mqttClient.ConnectAsync(options);
      
          if (connectResult.ResultCode == MqttClientConnectResultCode.Success)
          {   
              //连接成功后打印
              Console.WriteLine("\r\nConnected to MQTT broker successfully.\r\n");

              // Subscribe to a topic //订阅一个要接收的主题
              await mqttClient.SubscribeAsync(rsp_topic, MqttQualityOfServiceLevel.ExactlyOnce);//QOS=2
              // Callback function when a message is received //添加接收回调的消息
              mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync;

              //=======================================================================================       
              //开始发布消息        
              var message = new MqttApplicationMessageBuilder()
                  .WithTopic(req_topic)
                  .WithPayload(Data)
                  .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.ExactlyOnce)//QOS=2
                  .WithRetainFlag(false)
                  .Build();
              Console.WriteLine($"Send topic:{message.Topic}\r\nSend QoS:{message.QualityOfServiceLevel}\r\nSend RetainFlag: {message.Retain}\r\n");
              //发送一个主题消息
              await mqttClient.PublishAsync(message);
              // Wait for 1 second //自定义等待一段时间后关闭
              await Task.Delay(1000); 
              // Unsubscribe and disconnect//关闭接收主题
              await mqttClient.UnsubscribeAsync(rsp_topic);
              await mqttClient.DisconnectAsync();
              Console.WriteLine($"Unsubscribe and disconnect.\r\n");
          }
          else
          {
              Console.WriteLine($"Failed to connect to MQTT broker: {connectResult.ResultCode}");
          }
      }

     //回调函数,打印和传递订阅接收到数据
      private static Task MqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
      {
          Mqtt_Message_Received_Str = arg.ApplicationMessage.Payload;

          Console.WriteLine($"Received message:\r\n{Utils.bytesToString(Mqtt_Message_Received_Str)}\r\n[{arg.ApplicationMessage.Payload.Length}]\r\n");
          Console.WriteLine("Received topic:" + $"{arg.ApplicationMessage.Topic}\t\nReceived QoS:{arg.ApplicationMessage.QualityOfServiceLevel}\r\nReceived RetainFlag: {arg.ApplicationMessage.Retain}\r\n");
          return Task.CompletedTask;
      }

  }
}

2、 描述

  • 小结以上代码可以理解为3部分功能,创建连接、回调接收和发布消息。且3部分中均可以设置服务质量QoS(Quality of Service levels),确保可靠性传输,当然,服务器端也必须对标QOS设置:
    1、创建连接

    var connectResult = await mqttClient.ConnectAsync(options);

    2、回调接收

    mqttClient.ApplicationMessageReceivedAsync += MqttClient_ApplicationMessageReceivedAsync

    3、发布消息

    await mqttClient.PublishAsync(message);

    4、Qos设置
    参看代码备注 “//QOS=2”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1331441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

面试题 01.01. 判定字符是否唯一(优质解法)

链接&#xff1a;面试题 01.01. 判定字符是否唯一 代码&#xff1a; class Solution {public boolean isUnique(String astr) {//s[i]仅包含小写字母&#xff0c;数据范围小于 32 位&#xff0c;我们可以使用 int 变量的比特位来代替数组// 每个小写字符对应 bitMap 中的一个比…

Chatgpt如何共享可以防止封号!

ChatGPT 是一个基于 GPT-3.5/GPT-4 模型的对话系统&#xff0c;它主要用于处理自然语言对话。通过训练模型来模拟人类的语言行为&#xff0c;ChatGPT 可以通过文本交流与用户互动。每个新版本的 GPT 通常都会在模型规模、性能和其他方面有一些改进。在目前免费版GPT-3.5 中&…

【AI】Langchain-Chatchat搭建本地知识库-未完,先记录踩的坑

事先说一下&#xff0c;我本地的显卡4070只有12G显存&#xff0c;无法运行本地知识库&#xff0c;我把自己折腾的过程和遇到的坑先记录一下吧&#xff0c;后续如果有算力的话就再跑一遍试试。 Langchain-Chatchat曾用名Langchain-ChatGLM&#xff0c;是智谱AI的本地知识库项目&…

Qt前端技术:5.QSS

这个是表示QFrame中的pushButton中的子类和它子类的子类都将背景变为red 写成大于的时候表示只有直接的子类对象才会变 这个图中的QGroupBox和QPushButton都是QFrame的直接的子类 这个中的QGroupBox是QFrame的直接的子类但是QPushButton 是QGroupBox的子类&#xff0c;QPushB…

如何要做好年终绩效

年终绩效&#xff0c;每年12月份&#xff0c; 都是“绩效”这个词比较热门的阶段&#xff0c; 各个企业各个部门避不开的话题。 那如何能做好呢&#xff0c;一起来看看关于 要做好年终绩效考核、绩效面谈和绩效环评的建议吧&#xff01; 明确目标和指标&#xff1a;在考核开…

Tomcat远程调试

windows环境 写一个 startup-debug.bat&#xff0c;指定tomcat的根目录&#xff0c;端口自己定义 rem *******设置Tomcat目录*******-- set CATALINE_HOMED:\asd\A8-2\tomcat d: rem 8787为可用端口,为远程调试监听端口-- cd %CATALINE_HOME%/bin set JPDA_ADDRESS8787 set J…

JavaScript系列-函数调用之apply、call、bind

文章目录 适用场景apply定义语法具体的例子 call定义语法例子 bind定义例子语法多级绑定 小结更多内容 适用场景 apply、call、bind 三者都是 Function 原型上的方法&#xff0c;也就是说&#xff0c;基本所有函数都可以通过 函数名.apply|call|bind 调用 apply、call、bind …

centos7服务器安装 mysql

centos7服务器安装 mysql 一、下载 官网&#xff1a;https://dev.mysql.com/downloads/mysql/ 二、安装 1.查看有没有需要卸载的SQL包&#xff0c;一般系统的mariadb是自带的&#xff0c;需要卸载 rpm -qa | grep mysql rpm -qa | grep mariadb例如&#xff1a;安装过MySQL…

内存函数的学习

额外知识点 第一个 假设c为int类型&#xff0c;&#xff08;char&#xff09;c之后&#xff0c;之后如果还用变量c的话&#xff0c;c依然为int类型。&#xff08;&#xff09;强制转换操作符并不会永久改变原本的变量类型。 第二个 \0在打印时不会显示出来 第三个 void …

零成本搭建一款博客网站(基于Vercel+Hexo完美实现)【保姆级教程】

文章目录 &#x1f438;基于VercelHexo零成本搭建博客网站&#x1f43b;实现思路 &#x1f42e;Hexo的配置与安装&#x1f412;Hexo的美化与使用&#x1f42b;Github的推送与部署&#x1f43c;Vercel部署与网站上线&#x1f41b;总结 &#x1f438;基于VercelHexo零成本搭建博客…

Vue 实现响应式布局

实现响应式布局是工作中必不可少 客户需要 若是使用vue element ui 的方式实现 浏览器宽度为760的情况 浏览器宽度为360的情况 手机上的显示的情况 一、对于屏幕尺寸的定义 element UI参照Bootstrap的解决方案提供了五种屏幕大小尺寸&#xff1a;xs、sm、md、lg 和 xl。并对…

帮助谷歌从40人裂变为60000人的OKR是啥?

OKR&#xff08;Objectives and Key Results&#xff09;是一种目标管理方法&#xff0c;旨在帮助组织和个人明确目标并衡量成功。在谷歌的发展过程中&#xff0c;OKR扮演了至关重要的角色&#xff0c;帮助公司从40人规模快速成长为60000人的科技巨头。 OKR适用于各种类型的企…

Spring中你应该要知道的initMethod

文章目录 功能源码 功能 之前的文章中由解析过PostConstruct/PreDestroy&#xff0c;他们也是initMethod的一种形式&#xff0c;注解方式是后来才加入的&#xff0c;在源码中他们的命名都是一样的名字&#xff0c;都叫initMethod&#xff0c;不过他们却是有着很大的差别&#…

MySQL数据库基础和基本的增删改查操作

目录 前瞻 数据库的基本概念 数据库管理系统&#xff08;DBMS&#xff09; 数据库系统(DBS) 数据库类型和常用数据库 关系型数据库 SQL 非关系型数据库 NoSQL SQL语句 简介 SQL语句分类 常用的数据类型 MySQL的六大约束特性 SQL语句的使用 创建及删除数据库和表 …

quic协议及核心源码分析

quic协议 1、网络通信时&#xff0c;为了确保数据不丢包&#xff0c;早在几十年前就发明了tcp协议&#xff01;然而此一时非彼一时&#xff0c;随着技术进步和业务需求增多&#xff0c;tcp也暴露了部分比较明显的缺陷&#xff0c;比如: 建立连接的3次握手延迟大&#xff1b; T…

亚信安慧AntDB数据库荣获“2023年度信创卓越贡献奖”

近日&#xff0c;业界知名IT垂直门户媒体IT168公布“2023技术卓越奖”获奖名单&#xff0c;亚信安慧AntDB数据库荣获“2023年度信创卓越贡献奖”。 图1&#xff1a;亚信安慧AntDB数据库荣获“2023年度信创卓越贡献奖” “技术卓越奖”评选是IT168重要的年度奖项评选&#xff0c…

【Filament】纹理贴图

1 前言 本文主要介绍使用 Filament 实现纹理贴图&#xff0c;读者如果对 Filament 不太熟悉&#xff0c;请回顾以下内容。 Filament环境搭建绘制三角形绘制矩形绘制圆形绘制立方体 Filament 纹理坐标的 x、y 轴正方向分别朝右和朝上&#xff0c;其 y 轴正方向朝向与 OpenGL ES…

使用StableDiffusion进行图片Inpainting原理

论文链接&#xff1a;RePaint: Inpainting using Denoising Diffusion Probabilistic Models代码链接&#xff1a;RePaint Inpainting任务是指在任意一个二进制的掩码指定的图片区域上重新生成新的内容&#xff0c;且新生成的内容需要和周围内容保持协调。当前SOTA模型用单一类…

天文与计算机:技术的星辰大海

天文与计算机&#xff1a;技术的星辰大海 一、引言 在人类的历史长河中&#xff0c;天文学与计算机技术这两个领域似乎相隔甚远&#xff0c;然而在科技的推动下&#xff0c;它们却逐渐走到了一起&#xff0c;为人类对宇宙的探索开辟了新的道路。天文观测的复杂度与数据量随着…

C++初阶——类和对象

呀哈喽&#xff0c;我是结衣 C入门之后&#xff0c;我们就进入了C的初阶的学习了&#xff0c;在了解类和对象之前&#xff0c;我们还是先了解&#xff0c;面向过程和面向对象的初步认识。 在本篇博客中&#xff0c;我们要讲的内容有 1.面向过程和面向对象初步认识 2.类的引入 3…