mqttnet 详解_MQTTnet 3.0.5学习笔记

mqttnet 详解_MQTTnet 3.0.5学习笔记段时间在使用MQTTnet,都说这个东西比较好,可是翻了翻网上没有例子给参考一下。今天算是找到了,给高手的帖子做个宣传吧.由于GitHub上介绍的东西比较少,以我的水平真是不知道怎么用,先照葫芦画瓢,再看看怎么回事吧:功能:把订阅与发布做成一个类,还带有自动重连的功能usingSystem.Threading;usingSystem.Threading.Tasks;usingMQTTnet;usi…

大家好,又见面了,我是你们的朋友全栈君。

段时间在使用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 类里面都有什么东西

mqttnet 详解_MQTTnet 3.0.5学习笔记

需要实现的接口,如何实现,说重点!

在GitHub上有个地方进去看看就知道了‘

mqttnet 详解_MQTTnet 3.0.5学习笔记

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详细信息的类

mqttnet 详解_MQTTnet 3.0.5学习笔记

掉线的发生时会执行这个函数

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盘的根目录下就可以了

纸上得来终觉浅,要改造成自己想要的些东西,还要花些功夫!不过这已经很好了!谢谢各位高手的贡献

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/152862.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 数据仓库常见建模方法与大数据领域建模实例综述

    数据仓库常见建模方法与大数据领域建模实例综述为什么需要数据建模?为什么要进行数据仓库建模?随着DT时代互联网、智能设备等信息技术的发展,数据开始井喷式的增长,如何讲这些数据进行有序、有结构地分类组织存储是我们面临的一个挑战。如果把数据看作图书馆里的书,我们希望看到它们在书架上分门别类地放置,而不是乱糟糟的大数据的数仓建模是通过建模的方法更好的组织、存储数据,以便在性能、成本、效率和数据质量之间找到最佳平衡点。一般主要从下面四点考虑…

  • 下列选项中不符合python语言变量命名_以下变量名中,不符合Python语言变量命名规则的是…[通俗易懂]

    下列选项中不符合python语言变量命名_以下变量名中,不符合Python语言变量命名规则的是…[通俗易懂]摘要:备结械设在机中构可要点设计靠性,下语本出品可高产的根全型路和安是提靠性。名中命名不属标志别划目的品分的类常用于《危险类及化学分项是(。包括品中中不毒、符合措施预防危险污染化学事故控制。…备结械设在机中构可要点设计靠性,下语本出品可高产的根全型路和安是提靠性。》颁布了条例险化学品险化学品许可证管管理经营(第安全依据《危《危理办号令法》,变量不变量品经加强的管营许为了危险理化学可证。名中命名…

  • 配置注册表数据库损坏

    配置注册表数据库损坏

  • mysql开启慢日志查询_MySQL慢sql检验生效

    mysql开启慢日志查询_MySQL慢sql检验生效MySQL给我们提供了一个很好的功能,那就是慢查询!所谓的慢查询就是通过设置来记录超过一定时间的SQL语句!那么如何应用慢查询呢?1.开启MySQL的慢查询日志功能默认情况下,MySQL是不会记录超过一定执行时间的SQL语句的。要开启这个功能,我们需要修改MySQL的配置文件:windows下修改my.ini,(注册表,计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentCo…

    2022年10月14日
  • openCV._imread opencv

    openCV._imread opencv         近日,开始学习图像处理,思前想后决定以opencv作为实验基础。遂完成图片读取和显示功能。Imread作为常用的图像读取函数,虽然简单,但是参数的选择非常重要,直接影响到后期处理。同时在调试学习过程中也可以学习到图像处理的知识。1.函数原型Matimread(constString&amp;filename,intflags=IMREAD_COLOR)…

  • 子网掩码和通配符掩码的区别

    子网掩码和通配符掩码的区别子网掩码子网掩码,官方的定义是一种用来指明一个IP地址的哪些位标识的是主机所在的子网,以及哪些位标识的是主机的掩码。子网掩码不能单独存在,它必须结合IP地址一起使用。子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分。说白了子网掩码的工作原理就是,它拥有和主机IP地址一样的位数,每一位与对应的ip地址位进行“与”操作,得出的结果就是主机所在的子网,打个比方,…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号