【语言-c#】MQTT 订阅与发布

一、框架

windows 10

.NETFramework 4.6.1

MQTTnet 3.0.5.0

1、packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
  <package id="MQTTnet" version="3.0.5" targetFramework="net461" />
  <package id="NETStandard.Library" version="2.0.3" targetFramework="net461" />
  <package id="System.Net.Security" version="4.3.2" targetFramework="net461" />
  <package id="System.Net.WebSockets" version="4.3.0" targetFramework="net461" />
  <package id="System.Net.WebSockets.Client" version="4.3.2" targetFramework="net461" />
  <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
  <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
  <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
  <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
</packages>

原始文档

NuGet包

二、工具

org.eclipse.paho.ui.app-1.0.2-win32.win32.x86_64.zip(jdk-8u211-windows-x64.exe)

遇到问题

Paho
A Java Runtime Environment(JRE)or Java Development Kit (JDK) 
must be available in order to run Paho. No Java virtual machine 
was found after searching the following location:
...\org.eclipse.paho.ui.app-1.0.2-win32.win32.x86_64\jre\bin\javaw.exe
Javaw.exe in your current Path

解决方案

安装 JDK 并设置环境变量 , 如:Windows 10 x64 安装 "jdk-8u211-windows-x64.exe"

jdk-8u211-windows-x64.exe 配置

JDK 安装路径举例如下,以实际安装为准:
InstallPath JDK : C:\Program Files\Java\jdk1.8.0_211
InstallPath JRE : C:\Program Files\Java\jre1.8.0_211

[电脑-属性-高级系统设置-环境变量-系统变量]
1、添加
变量名:JAVA_HOME
变量值:C:\Program Files\Java\jdk1.8.0_211
2、添加
变量名:JRE_HOME
变量值:C:\Program Files\Java\jre1.8.0_211
3、添加
变量名:CLASSPATH
变量值:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
4、追加
变量名:Path
变量值:;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

三、管理 NuGet 程序包 

方法一、VS2013>工具>NuGet包管理器>程序包管理器控制台

NETStandard.Library

Install-Package NETStandard.Library –Version 2.0.3

MQTTnet

Install-Package MQTTnet –Version 3.0.5

方法二、VS2013>解决方案资源管理器>[Project]>引用(右键)>管理NuGet程序包(N)...

NETStandard.Library

MQTTnet

四、编写订阅和发布代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using MQTTnet.Packets;
using MQTTnet.Protocol;
using MQTTnet.Client.Receiving;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Connecting;

namespace CSDN
{
    class HOSMQTT
    {
        private static MqttClient mqttClient = null;
        private static IMqttClientOptions options = null;
        private static bool runState = false;
        private static bool running = false;

        /// <summary>
        /// 服务器IP
        /// </summary>
        private static string ServerUrl = "192.168.1.100";
        /// <summary>
        /// 服务器端口
        /// </summary>
        private static int Port = 61613;
        /// <summary>
        /// 选项 - 开启登录 - 密码
        /// </summary>
        private static string Password = "abcdefgh";
        /// <summary>
        /// 选项 - 开启登录 - 用户名
        /// </summary>
        private static string UserId = "administrator";
        /// <summary>
        /// 主题
        /// <para>China/Hunan/Yiyang/Nanxian</para>
        /// <para>Hotel/Room01/Tv</para>
        /// <para>Hospital/Dept01/Room001/Bed001</para>
        /// <para>Hospital/#</para>
        /// </summary>
        private static string Topic = "China/Hunan/Yiyang/Nanxian";
        /// <summary>
        /// 保留
        /// </summary>
        private static bool Retained = false;
        /// <summary>
        /// 服务质量
        /// <para>0 - 至多一次</para>
        /// <para>1 - 至少一次</para>
        /// <para>2 - 刚好一次</para>
        /// </summary>
        private static int QualityOfServiceLevel = 0;
        public static void Stop()
        {
            runState = false;
        }

        public static bool IsRun()
        {
            return (runState && running);
        }
        /// <summary>
        /// 启动客户端
        /// </summary>
        public static void Start()
        {
            try
            {
                runState = true;
                System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(Work));
                thread.Start();
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        private static void Work()
        {
            running = true;
            Console.WriteLine("Work >>Begin");
            try
            {
                var factory = new MqttFactory();
                mqttClient = factory.CreateMqttClient() as MqttClient;

                options = new MqttClientOptionsBuilder()
                    .WithTcpServer(ServerUrl, Port)
                    .WithCredentials(UserId, Password)
                    .WithClientId(Guid.NewGuid().ToString().Substring(0, 5))
                    .Build();

                mqttClient.ConnectAsync(options);
                mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(new Func<MqttClientConnectedEventArgs, Task>(Connected));
                mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(new Func<MqttClientDisconnectedEventArgs, Task>(Disconnected));
                mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(new Action<MqttApplicationMessageReceivedEventArgs>(MqttApplicationMessageReceived));
                while (runState)
                {
                    System.Threading.Thread.Sleep(100);
                }
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp);
            }
            Console.WriteLine("Work >>End");
            running = false;
            runState = false;
        }

        public static void StartMain()
        {
            try
            {
                var factory = new MqttFactory();

                var mqttClient = factory.CreateMqttClient();

                var options = new MqttClientOptionsBuilder()
                    .WithTcpServer(ServerUrl, Port)
                    .WithCredentials(UserId, Password)
                    .WithClientId(Guid.NewGuid().ToString().Substring(0, 5))
                    .Build();

                mqttClient.ConnectAsync(options);

                mqttClient.UseConnectedHandler(async e =>
                {
                    Console.WriteLine("Connected >>Success");
                    // Subscribe to a topic
                    var topicFilterBulder = new TopicFilterBuilder().WithTopic(Topic).Build();
                    await mqttClient.SubscribeAsync(topicFilterBulder);
                    Console.WriteLine("Subscribe >>" + Topic);
                });

                mqttClient.UseDisconnectedHandler(async e =>
                {
                    Console.WriteLine("Disconnected >>Disconnected Server");
                    await Task.Delay(TimeSpan.FromSeconds(5));
                    try
                    {
                        await mqttClient.ConnectAsync(options);
                    }
                    catch (Exception exp)
                    {
                        Console.WriteLine("Disconnected >>Exception" + exp.Message);
                    }
                });

                mqttClient.UseApplicationMessageReceivedHandler(e =>
                {
                    Console.WriteLine("MessageReceived >>" + Encoding.UTF8.GetString(e.ApplicationMessage.Payload));
                });
                Console.WriteLine(mqttClient.IsConnected.ToString());
            }
            catch (Exception exp)
            {
                Console.WriteLine("MessageReceived >>" + exp.Message);
            }
        }
        /// <summary>
        /// 发布
        /// <paramref name="QoS"/>
        /// <para>0 - 最多一次</para>
        /// <para>1 - 至少一次</para>
        /// <para>2 - 仅一次</para>
        /// </summary>
        /// <param name="Topic">发布主题</param>
        /// <param name="Message">发布内容</param>
        /// <returns></returns>
        public static void Publish( string Topic,string Message)
        {
            try
            {
                if (mqttClient == null) return;
                if (mqttClient.IsConnected == false)
                    mqttClient.ConnectAsync(options);

                if (mqttClient.IsConnected == false)
                {
                    Console.WriteLine("Publish >>Connected Failed! ");
                    return;
                }
                
                Console.WriteLine("Publish >>Topic: " + Topic + "; QoS: " + QualityOfServiceLevel + "; Retained: " + Retained + ";");
                Console.WriteLine("Publish >>Message: " + Message);
                MqttApplicationMessageBuilder mamb = new MqttApplicationMessageBuilder()
                 .WithTopic(Topic)
                 .WithPayload(Message).WithRetainFlag(Retained);
                if (QualityOfServiceLevel == 0)
                {
                    mamb = mamb.WithAtMostOnceQoS();
                }
                else if (QualityOfServiceLevel == 1)
                {
                    mamb = mamb.WithAtLeastOnceQoS();
                }
                else if (QualityOfServiceLevel == 2)
                {
                    mamb = mamb.WithExactlyOnceQoS();
                }

                mqttClient.PublishAsync(mamb.Build());
            }
            catch (Exception exp)
            {
                Console.WriteLine("Publish >>" + exp.Message);
            }
        }
        /// <summary>
        /// 连接服务器并按标题订阅内容
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private static async Task Connected(MqttClientConnectedEventArgs e)
        {
            try
            {
                List<TopicFilter> listTopic = new List<TopicFilter>();
                if (listTopic.Count() <= 0)
                {
                    var topicFilterBulder = new TopicFilterBuilder().WithTopic(Topic).Build();
                    listTopic.Add(topicFilterBulder);
                    Console.WriteLine("Connected >>Subscribe " + Topic);
                }
                await mqttClient.SubscribeAsync(listTopic.ToArray());
                Console.WriteLine("Connected >>Subscribe Success");
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp.Message);
            }
        }
        /// <summary>
        /// 失去连接触发事件
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        private static async Task Disconnected(MqttClientDisconnectedEventArgs e)
        {
            try
            {
                Console.WriteLine("Disconnected >>Disconnected Server");
                await Task.Delay(TimeSpan.FromSeconds(5));
                try
                {
                    await mqttClient.ConnectAsync(options);
                }
                catch (Exception exp)
                {
                    Console.WriteLine("Disconnected >>Exception " + exp.Message);
                }
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp.Message);
            }
        }
        /// <summary>
        /// 接收消息触发事件
        /// </summary>
        /// <param name="e"></param>
        private static void MqttApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            try
            {
                string text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                string Topic = e.ApplicationMessage.Topic;
                string QoS = e.ApplicationMessage.QualityOfServiceLevel.ToString();
                string Retained = e.ApplicationMessage.Retain.ToString();
                Console.WriteLine("MessageReceived >>Topic:" + Topic + "; QoS: " + QoS + "; Retained: " + Retained + ";");
                Console.WriteLine("MessageReceived >>Msg: " + text);
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp.Message);
            }
        }
    }
}

五、测试

1、启动

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSDN
{
    class Program
    {
        static void Main(string[] args)
        {
            HOSMQTT.Start();
        }
    }
}

2、使用Paho 工具发布消息

设置服务器IP和端口

设置用户名密码

连接服务

发布消息

监控订阅结果

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是STC89C52与ESP8266 ESP-01模块通过MQTT协议进行订阅消息的C语言代码: ```c #include "reg52.h" #include "stdio.h" #include "string.h" #include "stdlib.h" #define uchar unsigned char #define uint unsigned int sbit LED=P0^0; //LED灯连接P0.0口 //串口波特率设置 #define BAUD 9600 #define FOSC 11059200L #define T1MS (65536-FOSC/12/1000) //1ms定时器计数值 //MQTT服务器地址和端口 #define SERVER_IP "192.168.1.100" #define SERVER_PORT 1883 //订阅的主题 #define TOPIC "/test/topic" //ESP8266模块发送AT指令的函数 void esp8266_cmd(char* cmd) { char buf[100]; memset(buf, 0, sizeof(buf)); sprintf(buf, "%s\r\n", cmd); printf("%s", buf); while(1) { if(strstr(buf, "OK") || strstr(buf, "ERROR")) return; if(SBUF != 0) buf[strlen(buf)] = SBUF; } } //连接MQTT服务器 void mqtt_connect() { char cmd[100]; //发送MQTT连接请求 sprintf(cmd, "AT+CIPSTART=\"TCP\",\"%s\",%d\r\n", SERVER_IP, SERVER_PORT); esp8266_cmd(cmd); sprintf(cmd, "AT+CIPSEND=%d\r\n", 34 + strlen(TOPIC)); esp8266_cmd(cmd); printf("0104000000064d5154540402001e0004"); printf("%02x", strlen(TOPIC) >> 8); printf("%02x", strlen(TOPIC) & 0xff); printf("%s", TOPIC); while(1) { if(strstr(cmd, "SEND OK")) break; } } //订阅主题 void mqtt_subscribe() { char cmd[100]; sprintf(cmd, "AT+CIPSEND=%d\r\n", 35 + strlen(TOPIC)); esp8266_cmd(cmd); printf("8205"); printf("%02x", strlen(TOPIC) >> 8); printf("%02x", strlen(TOPIC) & 0xff); printf("%s", TOPIC); printf("00"); while(1) { if(strstr(cmd, "SEND OK")) break; } } //处理接收到的MQTT消息 void mqtt_process(char* msg) { if(strstr(msg, "ON")) LED = 0; else if(strstr(msg, "OFF")) LED = 1; } //接收串口数据中断处理函数 void serial_isr() interrupt 4 { if(RI == 1) { RI = 0; SBUF = P0; if(SBUF == '+') { char buf[100]; memset(buf, 0, sizeof(buf)); uint i = 0; while(1) { if(SBUF != 0) { buf[i++] = SBUF; if(i >= sizeof(buf)) break; if(strstr(buf, "OK") || strstr(buf, "ERROR")) break; } } if(strstr(buf, TOPIC)) { char msg[100]; memset(msg, 0, sizeof(msg)); uint j = 0; while(SBUF != 0) { msg[j++] = SBUF; if(j >= sizeof(msg)) break; } mqtt_process(msg); } } } } //定时器1中断处理函数 void timer1_isr() interrupt 3 { static uint cnt = 0; TH1 = T1MS >> 8; TL1 = T1MS & 0xff; if(++cnt >= 1000) { cnt = 0; LED = !LED; } } //主函数 void main() { //串口初始化 TMOD = 0x20; TH1 = T1MS >> 8; TL1 = T1MS & 0xff; TR1 = 1; SM0 = 0; SM1 = 1; REN = 1; ES = 1; EA = 1; //连接WiFi热点 esp8266_cmd("AT+CWMODE=1"); esp8266_cmd("AT+CWJAP=\"ssid\",\"password\""); //连接MQTT服务器并订阅主题 mqtt_connect(); mqtt_subscribe(); //循环等待接收MQTT消息 while(1); } ``` 需要注意的是,上述代码需要在STC89C52的环境下编译运行,且需要将ESP8266 ESP-01模块与STC89C52通过串口连接,同时需要将LED灯连接到P0.0口。另外,代码中的MQTT服务器地址、端口和订阅的主题需要根据实际情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值