mosquitto MQTT使用中遇到的问题.

Mosquitto是实现了MQTT的一个开源库.在网上有很多如何安装的例子,这里不在讲如何安装的问题,只是谈一下在使用的过程中遇到的一些问题.
 之前很奇怪网上在使用MQTT协议时,客户端大多使用paho的客户端,关于Mosquitto的客户端讲的比较少.不太清楚具体原因是什么.不过我在使用Mosquitto的客户端时确实遇到了些比较棘手的问题.
 首先蜗使用的是Mosquitto 1.5.5版本.使用客户端编译的库去连接服务器,服务器侧使用的是集群服务器,但是在实际使用中确实遇到一些问题.

一.关于连接服务器使用域名,还是IP进行连接.因为要对通信加密,服务器侧的同时就给了一个STL证书.在使用证书后,我写的客户端却怎么也连接不到服务器,一连接就出错.经过调查发现,给的这个证书中使用的是服务器域名,而蜗连接服务器时直接使用IP连接,导致开始认证总是通不过,因为客户端要检查服务器名字.解决方法有两个:
 1.设置mosquitto_tls_insecure_set(true),这样客户端不检测服务器名字.但是这样做存在一定的风险,如果有人伪装成服务器去连接客户端,可能会通过,导致安全风险.所以测试时可以这样设置,正式产品中不建议这样做.
 2.连接时直接传递域名进行连接.因为服务器侧是集群环境,避免了某个服务器坏了客户端连接不上.

二.由于MQTT大部分的应用场景是物联网,网络可能出现断网的情况.如果断网重连的话,重新连接后一定要再次订阅topic.不然对应的消息可能会收不到.尤其是在使用mosquitto的mosquitto_loop_forever()接口时,这个接口有自动重连的机制,开始我在使用的时候就忽略了这一点,导致自动重连的时候没有订阅topic.最好的做法是在connect的callback函数中设置订阅topic,这样每次重连后都能自动订阅.

三.还是关于网络重连问题,在使用mosquitto_loop_forever()接口后,在断开连接后会自动重连,就是默认设置是1s重连,但是在一开始的客户端mosquitto_connect()连接服务器时设置心跳时间默认是60s,这样导致的问题是,网络断开很快又恢复时,服务器的检测时间是60s,最差情况2分中才能检测到客户端掉线,而客户端1s后重连,这样服务器侧在某一时间会出现两个客户端连接,不知道是否是服务器的原因,理论上这时候应该踢掉前一个连接的客户端,可实际没有,因为我做的项目是直接使用的工业级服务器,所有任务是客户端存在问题,为避免这种情况就不能设置默认的时间,后来将心跳改为10s,自动重连时间设定20s,保证充足的时间服务器侧能检测到客户端掉线,避免同时存在多个客户端的情况.

四.关于moquitto1.5.5版本的一个Bug. 在使用的场景中网络并不稳定,时常会出现掉线问题,在掉线重连后居然出现QOS2的消息再也发送不出去, 出现下面这样的错误
Warning: Received PUBREC from cloud_123456 for an unknown packet identifier 10015…
 从网上查阅了很多资料都没有人提这个错误,在github上上也没有见到有人提这个bug.所有我开始怀疑是自己代码有问题.
本身该问题复现率就很低,调查了一个多月,查看mosquitto源码,最后找到了问题原因.在源码中重连时reset,清空Queue时存在bug. 文件messages_mosq.c中函数message__reconnect_reset()中prev指针在使用完后没有情况接着作为向外发送消息的指针使用,导致队列出现问题.本来向在github上提这个问题,不过在查看最新版的mosquitto后发现队列的整个实现方式已经变了,已经不会存在该问题,就没有载提这个问题,所有如果大家使用的时候最好使用mosquitto 1.6.3以后的版本.这也发现了开源的代码并不是完美的,也会存在各种各样的bug.

你可能感兴趣的:(linux)