前言
此教程是基于上一批教程,搭建云服务器并运行服务器,让我们的Hi3861连接上我们的服务器并传输数据。
在此之前,需要大家自己下载并配置好相关的代码,主要就是第三方MQTT代码,这个已经有大佬弄好了,我们跟着做就行了,轮子不需要每个人去做,我们需要做的是拿着别人做好的轮子来生产我们想要的车子。
大家可以先去连志安老师的文章,跟着教程一步一步的移植第三方MQTT库,然后再回来跟着我的教程走。
实现思路
先跟大伙说一下我的设计思路。MQTT是属于长连接的类型,他必须隔一段时间发送心跳包给服务器保持连接,这个叫做保活时间,只有发送心跳包给服务器并得到服务器的回复报文,那么设备才能长时间连接在服务器中。
那么问题来了,这种理想情况是出现在网络一直畅通的情况下产生,但是实际生活中会存在停电啊、断网等情况,导致设备无法连接到网络,那么这个情况,我们就需要 处理了,我们的设备在连上网之后,需要设置一个断线重连的机制,要不然,当你连上网之后,网络突然断开,然后又好了,那你的设备就无法继续上报数据了,所以我们需要一个断线重连的机制。流程图如下:
那么正常的流程应该是开机启动,任务执行,开始连接WiFi,连接成功之后,再去连接服务器,连接到服务器之后,就开始订阅主题,然后就可以发布数据,发布完数据之后隔一段时间(保活时间)发送心跳包到服务器,如果接受到服务器发送回来的报文,则证明连接正常,如果接收不到报文,证明与服务器的连接已经断开,那么断开后无非两种情况:
- 断网了
- 是WiFi连接正常,服务器不稳定导致断开
应对不同情况可以不同处理,我是直接一步到位,直接重连wifi,如果WiFi连接正常,依然发布不了数据,那可能就是服务器那边的问题。
如何判断WiFi是否连接异常
其实华为已经做好了重连机制,我们只需要设置一下标志位,然后在主循环中判断标志位即可。
下图为未打开指定wifi打印的log:
然后我打开指定的wifi后:
自动连接成功后,会重新连连接服务器,然后继续发布数据和发送心跳包,这样就可以实现断线重连机制,有的读者可能会问,为何不加一个判断服务器断线而不是wifi断开的机制呢,这里的话我是这么认为,除非有人恶意攻击你的服务器,否则一般情况下,你调试好连接到服务器后,只要不改变服务器地址和端口的话,在保活时间发送心跳包,基本不会出现服务器端断开的情况。
再者说这个只是个人的服务器,使用的时候直接打开服务器看看是否有数据收到就可以判断是否连接正常了,我这里也算是偷懒了,如果真的需要这个机制的话,也可以这么处理:
如果没有收到心跳包回复------>先重新连接MQTT服务器,如果连接成功了,那证明是和服务器端连接不稳定造成,如果连接不成功,那可以直接重新连接wifi,如果wifi连接不成功,那就证明是wifi问题了。这里也就对应上面流程图。
代码的实现
我这里是上报烟雾传感器AHT20的数据和温湿度传感器的数据,对应开发板的模块,可以直接拿过来用,MQTT和传感器的代码我就不多做解释了,有人已经造好轮子,没必要再造。我在前人的代码上添加自己机制,并把代码封装成模块,方便调用使用,先看wifi连接处理模块。
在头文件下:
外部声明一个变量判断wifi是否连接
在wifi_connect_fun.c中:
可以看到上面打印的WiFi: Connected,对应了我们打印的log,所以只需要在这里设置一下标志位,然后在主任务中判断。
然后在MQTT连接这个模块函数中,我把初始化、订阅主题、发布主题和发送心跳包封装起来了,直接在主函数中调用即可:
然后看主函数:
连接wifi的接口函数在初始化任务那里了。
然后把代码烧录到板子上,就可以在服务器中看到数据了。
设备端:
服务器端:
使用时注意事项
使用代码的时候,注意包含路径,让它编译进来: