mqttnet 详解_MQTTnet 3.0.5学习笔记
段时间在使用MQTTnet,都说这个东西比较好,可是翻了翻网上没有例子给参考一下。
今天算是找到了,给高手的帖子做个宣传吧.
由于GitHub上介绍的东西比较少,以我的水平真是不知道怎么用,先照葫芦画瓢,再看看怎么回事吧:
功能:
把订阅与发布做成一个类,还带有自动重连的功能
usingSystem.Threading;usingSystem.Threading.Tasks;usingMQTTnet;usingMQTTnet.Client; //客户端需要用到usingMQTTnet.Client.Options; //具体连接时需要用到的属性,ID的名称,要连接Server的名称,接入时用到的账号和密码,掉线时是否重新清除原有名称,还有许多...usingMQTTnet.Packets; //这个没用上usingMQTTnet.Protocol; //这个也没用上usingMQTTnet.Client.Receiving; //接收usingMQTTnet.Client.Disconnecting; //断线using MQTTnet.Client.Connecting; //连接
新建一个类:先写一下变量和一些字段
classHOSMQTT
{private static MqttClient mqttClient = null;private static IMqttClientOptions options = null;private static bool runState = false;private static bool running = false;///
///服务器IP///
private static string ServerUrl = "182.61.51.85";///
///服务器端口///
private static int Port = 61613;///
///选项 - 开启登录 - 密码///
private static string Password = "ruichi8888";///
///选项 - 开启登录 - 用户名///
private static string UserId = "admin";///
///主题/// China/Hunan/Yiyang/Nanxian
/// Hotel/Room01/Tv
/// Hospital/Dept01/Room001/Bed001
/// Hospital/#
///
private static string Topic = "China/Hunan/Yiyang/Nanxian";///
///保留///
private static bool Retained = false;///
///服务质量/// 0 - 至多一次
/// 1 - 至少一次
/// 2 - 刚好一次
///
private static int QualityOfServiceLevel = 0;
}
先看一下Start方法
public static voidStart()
{try{
runState= true;
Thread thread= newThread(Work); //原帖中是这样写的 Thread thread = new Thread(new ThreadStart( Work));
thread.IsBackground= true;
thread.Start();
}catch(Exception ex)
{
Console.WriteLine("启动客户端出现问题:" +ex.ToString());
}
}
没进入正题之前,先普及一下基本知识
多线程,new Thread(t1);和new Thread(new ThreadStart(t1));没有什么区别.前者是.net的写法,后者是C#的写法
具体请看下面的连接
进入整体,介绍连接方法 Work
private static voidWork()
{
running= true;Console.WriteLine("Work >>Begin");try{var factory = newMqttFactory(); //声明一个MQTT客户端的标准步骤 的第一步
mqttClient= factory.CreateMqttClient() asMqttClient; //factory.CreateMqttClient()实际是一个接口类型(IMqttClient),这里是把他的类型变了一下
options= newMqttClientOptionsBuilder() //实例化一个MqttClientOptionsBulider
.WithTcpServer(ServerUrl, Port)
.WithCredentials(UserId, Password)
.WithClientId("XMan")
.Build();
mqttClient.ConnectAsync(options); //连接服务器
//下面这些东西是什么,为什么要这么写,直到刚才我还是不懂,不过在GitHub的网址我发现了出处.
mqttClient.ConnectedHandler= new MqttClientConnectedHandlerDelegate(new Func(Connected));
mqttClient.DisconnectedHandler= new MqttClientDisconnectedHandlerDelegate(new Func(Disconnected));
mqttClient.ApplicationMessageReceivedHandler= new MqttApplicationMessageReceivedHandlerDelegate(new Action(MqttApplicationMessageReceived));while(runState)
{
Thread.Sleep(100);
}
}catch(Exception exp)
{
Console.WriteLine(exp);
}
Console.WriteLine("Work >>End");
running= false;
runState= false;
}
先来看看MqttClient 类里面都有什么东西
需要实现的接口,如何实现,说重点!
在GitHub上有个地方进去看看就知道了‘
private voidSomething()
{
mqttClient.ApplicationMessageReceivedHandler= newMqttApplicationMessageReceivedHandlerDelegate(OnAppMessage);
mqttClient.ConnectedHandler= newMqttClientConnectedHandlerDelegate(OnConnected);
mqttClient.DisconnectedHandler= newMqttClientDisconnectedHandlerDelegate(OnDisconnected);
}private async voidOnAppMessage(MqttApplicationMessageReceivedEventArgs e)
{
}private async voidOnConnected(MqttClientConnectedEventArgs e)
{
}private async voidOnDisconnected(MqttClientDisconnectedEventArgs e)
{
}
在开始Connected方法之前有必要看一下关于同步和异步的知识,
现学现卖简单说一下:
Task就是异步的调用,就在不影响主线程运行的另一个线程,但是他能像线程池一样更高效的利用现有的空闲线程
async必须用来修饰Task ,void,或者Task, await是等待异步线程Task.Run()开始的后台线程执行完毕。
记住要是Task 实现异步功能,必须用 async 修饰,且async 与await成对出现。
下面是什么意思?
mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(new Func(Connected));
MqttClientConnectedHandlerDelegate 这个实例实现了mqttClient.ConnectedHandler接口
new Func(Connected) ,
使用Func委托传入MqttClientConnectedEventArgs类型的参数,返回的类型是Task,Task是一个类,这个类没有返回值,如果有返回值就是Task。
是委托就要带一个方法取实现,这个方法就是Connected。
这句话的意思是,用MqttClientConnectedHandlerDelegate实现接口,同时使用委托取调用Connected的方法,并且给这个方法传入一个MqttClientConnectedEventArgs参数,
这个委托的返回值是Task(就是不需要返回类型的异步调用),这也就定义了Connected的类型必须是async Task。
好了来看下 Connected,这个函数什么意思
就是与服务器连接之后要干什么,订阅一个Topic,或几个Topic。连接之前已经连接了Connectasync(),如果断线还会重连,后面会提到。
这个就连接之后需要做的事----订阅!
private static asyncTask Connected(MqttClientConnectedEventArgs e)
{try{
List listTopic = new List();if (listTopic.Count() <= 0)
{var topicFilterBulder = newTopicFilterBuilder().WithTopic(Topic).Build();
listTopic.Add(topicFilterBulder);
Console.WriteLine("Connected >>Subscribe" +Topic);
}awaitmqttClient.SubscribeAsync(listTopic.ToArray());
Console.WriteLine("Connected >>Subscribe Success");
}catch(Exception exp)
{
Console.WriteLine(exp.Message);
}
}
TopicFilter是一个Topic详细信息的类
掉线的发生时会执行这个函数
private static asyncTask Disconnected(MqttClientDisconnectedEventArgs e)
{try{
Console.WriteLine("Disconnected >>Disconnected Server");await Task.Delay(TimeSpan.FromSeconds(5));try{awaitmqttClient.ConnectAsync(options);
}catch(Exception exp)
{
Console.WriteLine("Disconnected >>Exception" +exp.Message);
}
}catch(Exception exp)
{
Console.WriteLine(exp.Message);
}
}
越写问题越多,这个为什么断线的时候会执行这个方法,这不是事件,只是接口!
怎么实现的?看了一下源码,一时只看了大概,这些功能的绑定都是在ConnectAsync的时候就完成了!
下面接收到消息的时候
///
///接收消息触发事件///
///
private static voidMqttApplicationMessageReceived(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);
}
}
最后就是发布:一般会选择0,如果选择其他的情况在订阅端不在的时候,服务器可能会崩溃
///
/// ///发布///
/// 0 - 最多一次
/// 1 - 至少一次
/// 2 - 仅一次
///
/// 发布主题
/// 发布内容
///
public static void Publish( string Topic,stringMessage)
{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= newMqttApplicationMessageBuilder()
.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);
}
}
重点补充一下:
这两天验证的时候发现,对于MQTT服务器来说客户端的用户名必须是唯一的,
举例:同一台电脑上,两个程序同时发布(publish)到一个MQTT服务器,必须设置两个不同的ClientId,否则只有一个能连接上。
Paho的使用:
具体说明也可以看这位高手的:
只是有一点需要强调以下:
Paho的目录不要太深,之前我就是三层文件夹下面,结果无法运行。一直提示 error code=13
没办法把他放在D盘的根目录下就可以了
纸上得来终觉浅,要改造成自己想要的些东西,还要花些功夫!不过这已经很好了!谢谢各位高手的贡献
mqttnet 详解_MQTTnet 3.0.5学习笔记相关推荐
- git reset 命令详解(一)—— Git 学习笔记 07
git reset 命令详解(一) 简而言之,git reset 命令是用来将当前 branch 重置到另外一个 commit 的,这个动作可能同时影响到 index 以及 work director ...
- git reset 命令详解(二)—— Git 学习笔记 08
git reset 命令详解(二) 上一篇博文git reset 命令详解(一)讲了 git reset 命令的基本原理和用法,这篇博文谈一谈 git reset 的另一种用法--后面跟一个路径(或文 ...
- 【BackEnd--SSM 框架详解】Mybatis+Spring+SpringMVC学习笔记(完整详细版)
BackEnd 学习笔记 1 Java 2 SSM框架(Mybatis+Spring+SpringMVC) 3 SpringBoot(SpringBoot 3.x+MybatisPlus) 4 Spr ...
- 网络请求的基本知识《极客学院 --AFNetworking 2.x 网络解析详解--1》学习笔记...
2019独角兽企业重金招聘Python工程师标准>>> 网络请求的基本知识 我们网络请求用的是HTTP请求 Http请求格式:请求的方法,请求头,请求正文 Http请求的Requ ...
- 【网络协议详解】——IPv6协议(学习笔记)
目录
- [Unity官方直播] 详解Unity Asset的一生——学习笔记(一)
文章目录 呱呱坠地--Asset的产生 1.根据产生方式分类 2.根据使用时期分类 成长的烦恼--Asset导入设置 1.重要的Meta文件 2.拥挤的Library文件夹 3.神奇的Streamin ...
- 《C# 语言入门详解(刘铁锰) - 学习笔记 - Lambda表达 / Linq查询》
Lambda表达 / LINQ查询 文章目录 Lambda表达 / LINQ查询 前言 一.Lambda表达式 二.LINQ查询 前言 Lambda表达式: 匿名方法.inline(内联)方法.(简化 ...
- 详解分析MySQL8.0的内存消耗
文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 目录 1.innodb_ ...
- 详解JPA 2.0动态查询机制:Criteria API
转载自详解JPA 2.0动态查询机制:Criteria API-51CTO.若有侵权,请留言删除. 自从 JPA 于 2006 年首次被引入之后,它就得到了 Java 开发社区的广泛支持.该规范的下一 ...
最新文章
- 做程序猿的老婆应该注意的一些事情
- 电子工程师要学的课程有哪些?
- 【Python】python 反射机制在实际的应用场景讲解
- inode与ln命令
- 中关村win11 32位官方原版iso文件v2021.08
- python使用opencv_教你快速使用OpenCV/Python/dlib進行眨眼檢測識別!
- 深度学习(四十)优化求解系列(2)简单理解神经网络求解过程-未完待续
- 计算机环形拓扑结构教案,面试真题高中信息技术《网络拓扑结构》教学设计...
- 桶排序JAVA软件测试_111-堆排序的速度测试和小结
- 吴恩达机器学习作业Python实现(三):多类分类和前馈神经网络
- SpringActionscript3 片断
- 我的世界怎么修改服务器文本,《我的世界手机版》如何修改界面文本 自定义语言教程...
- 普元EOS7.5生成RestFul接口服务
- 简单几何图形绘制总结
- 根据股票涨跌用KMeans进行分类
- JavaScript学习第十九天
- 远程连接内网路由器下的电脑
- 中国“钱”途光明10所大学
- 化繁为简,聊一聊复制状态机系统架构抽象
- python多维字典_python定义多维字典
热门文章
- 关联规则概念、啤酒加尿布引出购物篮分析、频繁项集、支持度+置信度+提升度
- keras构建前馈神经网络(feedforward neural network)进行回归模型构建和学习
- 辽宁交通高等专科学校计算机专业,辽宁省交通高等专科学校怎么样 全国排名第几...
- oracle 复制表方法,(转)oracle数据库之间 表复制方法一(extent 方法)
- python字典按value逆序排序_python 对字典按照value进行排序的方法
- java.lang.UnsatisfiedLinkError:no jhdf5 in java.library.path问题的解决
- C++的类什么时候需要虚析构函数
- LLVM系列文章1: Debian/Ubuntu 安装和使用 LLVM
- Python scapy库监听网卡,抓取HTTP包
- python操作mongodb进行读写