开发者学堂课程【嵌入式之 RFID 开发与应用2020版:MQTT -基于 mosquitto 开源软件应用开发介绍】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/665/detail/11182
MQTT -基于 mosquitto 开源软件应用开发介绍
内容介绍:
一、mosquitto 的开发
二、服务器的连接
三、主事件循环是什么
一、mosquitto 的开发
根据移植好的开源 MQTT 的软件,在此基础上来完成终端的应用开发。 一般这个开发的基于终端的比较多,除非做服务端的开发,首先对于 mosquitto 来说要去完成这个开发,它有一系列的函数接口的提供,而且官方提供了完善的数据手册,首先简单来看一下几个主要的函数, mosquitto 的这个库提供的函数,几乎都是配对的,而且很多函数都是以回调的方式, 很多这个接口都安插了回调函数接口来实现网络通信。首先就是初始化,一开始的时候就要初始化, 完成一些全局变量,包括一些环境的配置与网络相关的。最后结束了要清除这就是配对的 int mosquitto_lib_init(viid) int mosquitto_lib_cleanup(),
接下来初始化环境之后就要作为客户端联网, 不管是发布还是订阅都要去创建一个客户端,客户端的创建 ,其实就是完成了 mosquitto 的句柄。后面几乎所有的操作不管是设置参数、连接服务器、断开服务器、 发布订阅都是基于返回值去实现的,可以传递一些参数,比如用户的 ID 还有消息到服务器之后是否要保留以及后面很多的回调函数,每一次回调函数都会有一个参数,它的参数可以是创建客户端的时候就会指定,指定可能是一个结构体的地址,也可能是一个不确定的,自己可以任意去设置的参数。与新建客户端所对应的就是释放客户端 mosquitto_destory(struct mosquitto*mosq)
,释放的参数刚好领就是新建的返回值, mosquitto_destory(struct mosquitto*mosq)
这个是配对的, int mosquitto_lib_init(void) ;int mosquitto_lib_cleanup
也是配对的。
接下来的 void mosquitto_connect_callback_set(struct mosquitto *mosq),void (*on _connect)
就是一些常规的这种接口比如说有没有连接上回调函数,通过 connect_callback_set 去设置连接回调函数,回调函数在 on connect 是没有返回值的,而且还需要有 struct mosquitto *mosq(客户端数据)、void*obj(创建客户端时的回调参数) 、int rc//0(表示连接成功,其他表示失败)三个参数,通过三个参数就可以判断当前的确认连接的情况,然后接下来就是断开,一个是连接一个断开, 断开也有一个回调的函数,基本上跟连接的回调函数类似。
二、连接服务器
接下来是真正的连接服务器,不管是发布和订阅,都要先连接服务器 所以这个是很重要的,连接服务器的时候,首先是句柄,然后就是服务器的IP地址 ,服务器的端口号,包括跟服务器之间的一个心跳包的时间间隔。struct mosquitto *mosq(客户端)、const char*host(服务器ip地址)、int port(服务端口号)、int keepalive(保持连接的时间间隔,单位秒)当收到了订阅的消息之后,那么由 void mosquitto_message_callback_set 这个函数来实现对消息内容的处理,那么它的这个消息就是 mosquitto message *message ,后面会有一个结构体,会告知消息结构体都包含了哪些信息,收到消息就会回调。首先是 int mid(消息 ID ) ,ID 实际上是可以自由分配的,发布的时候也可以指定另外的话就是 char*topic(主题),void*payload(主题对应的内容,mqtt 中有效载荷)还有 int payloadlen (消息的长度),包括 int qos (服务质量)以及 bool retain (消息是否有保留)等等。再接下来就是在订阅的时候,提交订阅之后会有一个订阅回调,就是反馈这个订阅是不是成功的,也会有一个就不是收到消息的回调了,而是向服务器提交订阅请求的时候的一个回调,最后两个非常重要的接口,一个是订阅,一个是发布。订阅就是告诉服务器当前要针对于哪个消息、哪个主题、什么样的质量进行监听,发布也是一样的就是要给哪个主题发多长的内容、发的内容是什么、质量是多少、是否要保留这个消息。char*topic (主题),void*payload (主题对应的内容,mqtt 中有效载荷)还有 int payloadlen (消息的长度),包括 int qos (服务质量)以及 bool retain (消息是否有保留)
三、主事件循环是什么
所有的事件都处理好之后会有一个循环处理即所谓的主事件循环, 主事件循环是在 mosquitto_loop 里面去完成的,主要是完成一些网络事件的监听,包括一些回调的处理,这个函数是要不断的去调用的,如果一旦不调用可能就会丢失一些数据,所以这个函数一定是一个进程或者线程, 进程或线程是怎么创建出来的,只需要在程序当中去调 mosquitto _loops_start 这个函数,它自动会创建一个线程,然后由线程去允许,如果自己去调也是可以的,自己去调相当于就要自己创建一个进度和线程,会影响主程序的顺序。因为调用 mosquitto _loops,它不堵塞了或者是说通过一个进程线程调查。最后在整个结束的时候,会通过 mosquitto_ 这个函数去进行监听是否退出, 如果退出的话需要去释放资源 ,包括通过参数可以去指定是强行退出,还是断网以后再退出。Int mosquitto_loop_start(struct mosquitto *mosq)
通过创建新的线程不断调用 mosquitto-loop()函数处理事件不堵塞。网络事件阻塞回收结束处理函数;int mosquitto_loop-stop(struct moaquitto *mosq,bool force)
。
接下来就重点看一下实现,通过源代码的方式去分析一下,代码其实比较简单,目的是为了客户端正常的运行,这里建议在 mkdir目录建立 src,src 就是源代码,自己写代码的一个目录 。进去之后代码直接就拷贝
用 PC 端的方式,是交叉编译,为什么交叉编译, 因为大多数时候开发的其实是终端的设备,PC 端其实相对来说要简单一些,所以 arm 拿过来,拷过来之后所使用的环境、库这些就应该是刚刚编出来的那套东西, 比如说首先第一个要指定 MQTT 的一个文件,那 MQTT 就是在 mosquitto-1.5.4, 开发版的不是 PC 的。 应该是1.5.4这个版本里面要把这个路径 home/edu/debug/mqtt/mosquitto-1.5.4 复制 mqtt 是指定的,那接下来还有 openssl, 退回去进到 openssl , -install 里面,它也是 home/edu/debug/mqtt/mosquitto- 1.0.1 这个路径。
完了之后是 uuid,libuuid_1.0.3_install$ 路径,/home/edu/debug/mqtt/libuuid 是交叉编译的路径,
交叉编译的路径就设置成功,成功之后先不看代码,主要先把环境搭好 ,这个时候去编一下,出现了一些问题,路径是正确的,问题是只指定了 include,还要指定 library 。指定完成后就编过了,那么下一节课再来分析具体的源代码,先把环境先搭好 这个环境就可以了 。