基于C#实现MQTT通信实战

 更新时间:2025年05月18日 11:35:44   作者:绿龙术士  
MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现MQTT通信实战的相关方法吧

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 进入面板。

在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.ReasonString}" + Environment.NewLine + this.log.Text;
        return;
    }

2、订阅消息

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

    // 订阅消息
    var option = 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>()
    {
        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.IsSuccess == 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通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C# 获取程序集版本、文件版本

    C# 获取程序集版本、文件版本

    C# 获取程序集版本、文件版本的实现代码。
    2009-09-09
  • C#使用AutoResetEvent实现同步

    C#使用AutoResetEvent实现同步

    这篇文章主要为大家详细介绍了C#使用AutoResetEvent实现同步的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • C# 利用ICSharpCode.SharpZipLib实现在线压缩和解压缩

    C# 利用ICSharpCode.SharpZipLib实现在线压缩和解压缩

    本文主要主要介绍了利用ICSharpCode.SharpZipLib第三方的DLL库实现在线压缩和解压缩的功能,并做了相关的代码演示。
    2016-04-04
  • c#打开py文件的方法

    c#打开py文件的方法

    在本篇内容里小编给大家分享的是关于c#打开py文件的方法和步骤,需要的朋友们可以跟着学习下。
    2018-12-12
  • C#控制图像旋转和翻转的方法

    C#控制图像旋转和翻转的方法

    这篇文章主要介绍了C#控制图像旋转和翻转的方法,涉及C#图像操作中RotateFlip方法的相关使用技巧,需要的朋友可以参考下
    2015-06-06
  • 关于C#执行顺序带来的一些潜在问题

    关于C#执行顺序带来的一些潜在问题

    这篇文章主要给大家介绍了关于C#执行顺序带来的一些潜在问题,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-08-08
  • C#实现的最短路径分析

    C#实现的最短路径分析

    C#实现的最短路径分析,需要的朋友可以参考一下
    2013-03-03
  • C#实现简易计算器

    C#实现简易计算器

    这篇文章主要为大家详细介绍了C#实现简易计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-01-01
  • C#数据类型转换(显式转型、隐式转型、强制转型)

    C#数据类型转换(显式转型、隐式转型、强制转型)

    本文详细讲解了C#数据类型转换(显式转型、隐式转型、强制转型),文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • Unity中 mesh生成斜坡的示例代码

    Unity中 mesh生成斜坡的示例代码

    Mesh是指模型的网格,3D模型是由多边形拼接而成,而多边形实际上是由多个三角形拼接而成的,今天通过本文给大家介绍Unity中 mesh生成斜坡功能,感兴趣的朋友一起看看吧
    2021-05-05

最新评论