基于C#实现MQTT通信实战

2025-05-18 14:50

本文主要是介绍基于C#实现MQTT通信实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现...

MQTT(Message Queueing Telemetry Transport) 消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点。

它被设计用于低带宽,不稳定或高延迟的网络环境,因此非常适合于设备之间的数据通信。

EMQX提供了MQTT的服务器,并且可以在后台网页查看面板,还支持中文显示。

由于5.0之后的版本不再支持Windows所以使用的是4.0版本的包,在下载完压缩包后,不用安装,进入cmd导航到安装的bin目录下(注意:路径中不能包含中文),执行命令:emqx start,看见没有报错就说明启动成功了。

之后在浏览器里输入:http://127.0.0.1:18083 进入面板。

基于C#实现MQTT通信实战

在WebSocket菜单里可以模拟发布/订阅的操作,接下来我们将使用C#完成这一系列的操作。

1、连接主机

首先新建一个wpF项目,然后在Nuget中下载MQTTnet。

    // 连接主机
    MqttFactory factory = new MqttFactory();
    _client = factory.CreateMqttClient();
    var options = new MqttClientOptionsBuilder().
        WithtcpServer(this.ipAddress.Text, Convert.ToInt32(this.port.Text))
        .WithClientId(this.clientId.Text)
        .Build();
    var result = await _client.ConnectAsync(options, CancellationToken.None);
    if (result.ResultCode == MqttClientConnectResultCode.Success)
    {
        this.log.Text = DateTime.Now.ToString() + "    连接成功" + Environment.NewLine + this.log.Text;
    }
    else
    {
        this.log.Text = DateTime.Now.ToString() + $"    连接失败,{result.Re编程asonString}" + Environment.NewLine + this.log.Text;
        return;
    }

2、订阅消息

订阅消息分为两块,一个是消息的回显,一个是订阅消息。

    // 订阅消息
    vaChina编程r optiolwYQNqVKPyn = new MqttClientSubscribeOptions();
    MqttQualityOfServiceLevel level;
    switch (this.subscribeQos.SelectedIndex)
    {
        case 0:
            level = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce;
            break;
        case 1:
            level = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce;
            break;
        case 2:
            level = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce;
            break;
        default:
            throw new Exception("请选择服务质量");
    }
 
    option.TopicFilters = new List<MqttTopicFilter>android()
    {
        new MqttTopicFilter()
        {
            Topic = this.subscribeTopic.Text,
            QualityOfServiceLevel = level
        }
    };
    this._client.SubscribeAsync(option, CancellationToken.None);
 
    // 将订阅的消息回显到日志区
    this._client.ApplicationMessageReceivedAsync += e =>
    {
        var task = Task.Factory.StartNew(() => {
            try
            {
                var array = e.ApplicationMessage.PayloadSegment.Array;
                if (array == null)
                {
                    return;
                }
 
                var str = Encoding.UTF8.GetString(array);
 
                // 跨线程更新UI
                Application.Current.Dispatcher.Invoke(() => {
                    this.log.Text = DateTime.Now.ToString() + "    收到消息:" + str + Environment.NewLine + this.log.Text;
                });
            }
            catch (Exception ex)
            {
                this.log.Text = DateTime.Now.ToString() + $"    {ex.Message}" + Environment.NewLine + this.log.Text;
            }
        });
 
        return task;
    };
 
    this.log.Text = DateTime.Now.ToString() + "    订阅成功" + Environment.NewLine + this.log.Text;

订阅消息只需要两个参数:主题Topic和服务质量QoC,主题是用来区分不同频段的消息,避免出现冲突,如果想接收到所有的消息可以这么写:topicXXX/#,#就代表不限制范围,如果打算只接受固定区域的消息,则需要将#改成某个字符串。

服务质量QoC是用来控制可用性的,0是最低等级,最多只发送一次,1是中级,至少发一次,但有可能出现重复接收的情况,2是最高级,只发一次,不会多也不会少。

将消息回显需要注册ApplicationMessageReceivedAsync事件,传入的参数是回显对象,返回值是一个Task类型,是在Task中获取回显的值并完成控件的更新操作。

3、发布消息

发布消息的参数比订阅多两个:消息内容Payload,持久会话(在恢复连接后保留之前的订阅和消息传递状态)

    var msg = new MqttApplicationMessage();
    msg.Topic = this.topic.Text;
    msg.PayloadSegment = Encoding.UTF8.GetBytes(this.msg.Text);
    msg.Retain = isSave.IsChecked??false;
    MqttQualityOfServiceLevel level;
    switch (this.publishQos.SelectedIndex)
    {
        case 0:
            level = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce;
            break;
        case 1:
            level = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce;
            break;
        case 2:
            level = MQTTnet.Protocol.MqttQualityOfServiceLevel.ExactlyOnce;
            break;
        default:
            throw new Exception("请选择服务质量");
    }
    
    msg.QualityOfServiceLevel = level;
    var resultPublish = await _client.PublishAsync(msg, CancellationToken.None);
    if (resultPublish.jsIsSuccess == true)
    {
        this.log.Text = DateTime.Now.ToString() + "    发送成功" + Environment.NewLine + this.log.Text;
    }
    else
    {
        this.log.Text = DateTime.Now.ToString() + "    发送失败" + Environment.NewLine + this.log.Text;
    }

到此这篇关于基于C#实现MQTT通信实战的文章就介绍到这了,更多相关C# MQTT通信内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于基于C#实现MQTT通信实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154650

相关文章

Java实现视频格式转换的完整指南

《Java实现视频格式转换的完整指南》在Java中实现视频格式的转换,通常需要借助第三方工具或库,因为视频的编解码操作复杂且性能需求较高,以下是实现视频格式转换的常用方法和步骤,需要的朋友可以参考下... 目录核心思路方法一:通过调用 FFmpeg 命令步骤示例代码说明优点方法二:使用 Jaffree(FF

Java实现图片淡入淡出效果

《Java实现图片淡入淡出效果》在现代图形用户界面和游戏开发中,**图片淡入淡出(FadeIn/Out)**是一种常见且实用的视觉过渡效果,它可以用于启动画面、场景切换、轮播图、提示框弹出等场景,通过... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细

Python实现获取带合并单元格的表格数据

《Python实现获取带合并单元格的表格数据》由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,所以本文我们就来聊聊如何使用Python实现获取带合并单元格的表格数据吧... 由于在日常运维中经常出现一些合并单元格的表格,如果要获取数据比较麻烦,现将将封装成类,并通过调用list_exc

Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例

《Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例》本文介绍Nginx+Keepalived实现Web集群高可用负载均衡的部署与测试,涵盖架构设计、环境配置、健康检查、... 目录前言一、架构设计二、环境准备三、案例部署配置 前端 Keepalived配置 前端 Nginx

Python日期和时间完全指南与实战

《Python日期和时间完全指南与实战》在软件开发领域,‌日期时间处理‌是贯穿系统设计全生命周期的重要基础能力,本文将深入解析Python日期时间的‌七大核心模块‌,通过‌企业级代码案例‌揭示最佳实践... 目录一、背景与核心价值二、核心模块详解与实战2.1 datetime模块四剑客2.2 时区处理黄金法

使用animation.css库快速实现CSS3旋转动画效果

《使用animation.css库快速实现CSS3旋转动画效果》随着Web技术的不断发展,动画效果已经成为了网页设计中不可或缺的一部分,本文将深入探讨animation.css的工作原理,如何使用以及... 目录1. css3动画技术简介2. animation.css库介绍2.1 animation.cs

Java进行日期解析与格式化的实现代码

《Java进行日期解析与格式化的实现代码》使用Java搭配ApacheCommonsLang3和Natty库,可以实现灵活高效的日期解析与格式化,本文将通过相关示例为大家讲讲具体的实践操作,需要的可以... 目录一、背景二、依赖介绍1. Apache Commons Lang32. Natty三、核心实现代

C#特性(Attributes)和反射(Reflection)详解

《C#特性(Attributes)和反射(Reflection)详解》:本文主要介绍C#特性(Attributes)和反射(Reflection),具有很好的参考价值,希望对大家有所帮助,如有错误... 目录特性特性的定义概念目的反射定义概念目的反射的主要功能包括使用反射的基本步骤特性和反射的关系总结特性

SpringBoot实现接口数据加解密的三种实战方案

《SpringBoot实现接口数据加解密的三种实战方案》在金融支付、用户隐私信息传输等场景中,接口数据若以明文传输,极易被中间人攻击窃取,SpringBoot提供了多种优雅的加解密实现方案,本文将从原... 目录一、为什么需要接口数据加解密?二、核心加解密算法选择1. 对称加密(AES)2. 非对称加密(R

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细