物联网协议MQTT已经发布很久了,也火了好一阵子了,因为工作一直没怎么接触,所以也一直停留在“知道”阶段近期,因为工作需要把采集的数据上云平台,最开始关注的是阿里的IOT平台,然后是阿里的C-SDK, 为了对SDK有更深度的理解,顺便看了MQTT的协议。自己感觉对MQTT的订阅、发布模式有了一点感觉了,在此做个笔记,免得遗忘。如果能帮到和我一样的初学者,那是在好不过了。
因为只熟悉熟悉C语言,加上懂点点单片机,所以终端我关注的是阿里的IOT C-SDK。 阿里的IOT平台可以通过多种协议(例如http)接入,我只关注了MQTT协议的接入部分。
简单点理解,MQTT是一个C/S系统,采用TCP长连接,所有终端作为TCP-Client连接到MQTT服务端(他们起了个专用的名字叫MQTT-Broker)。 阿里IOT云平台, 你可以理解成一个功能非常完备的mqtt-broker;接入平台的设备就是终端。 其实,如果熟悉linux, 可以在linux下直接安装一个mosquitto,用来做自己的MQTT-broker, ubutun下面安装非常方便(可以参考:https://blog.csdn.net/swedenfeng/article/details/53510048)。mosquitto也有相应的windows版本安装包。
MQTT-broker 它就是个数据中转中心, 设备之间的交流, 必须通过MQTT-broker进行转发。 终端【发布】消息到MQTT-broker 。如果其他终端想“看到”这个消息,则需要通过发布订阅消息到MQTT-broker来通知MQTT-broker,把收到的上行消息转发给自己。 为了对消息进行区分, 这些消息在系统内应该有一个统一的标识(topic)。发布消息,订阅消息,都需要指定该消息的topic。
MQTT协议,推荐看这里:http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html#fixed-header
熟悉windows下VS开发的同学, 想通过代码调试理解MQTT协议,可以看看这个老师的文章:https://cloud.tencent.com/developer/article/1601052, 他还开源了一个VS2013的C++工程(https://github.com/xidongliang/mqtt_client/),方便我们理解MQTT的通信过程。但使用自己的mosquitto做前端测试时, 我发现工程在收到订阅消息,mosquitto前端会吧tcp连接断开。mosquitto日志提示协议错误。仔细看看了看MQTT协议文档, 发现发布QOS=0的消息时, 不应该应答MQTT_MSG_PUBREL消息。
根据MQTT协议要求, 终端上线时, CONNECT消息需要3个参数:
char clientId[150];
char username[65];
char password[65];
我想用这个VS2013工程接入阿里云平台, 这三个参数哪里来呢?原来阿里IOT平台接入时,需要一个设备4元组
#define EXAMPLE_PRODUCT_KEY "a1ddsgdi0r"
#define EXAMPLE_PRODUCT_SECRET "iXmb3q7GD5g9Orx"
#define EXAMPLE_DEVICE_NAME "DemoDevice"
#define EXAMPLE_DEVICE_SECRET "d68567cadd0bf3eeee5c3a1106512"
接入阿里云平台, 需要根据
#define EXAMPLE_PRODUCT_SECRET "iXmb3q7GD5g9Orx"
#define EXAMPLE_DEVICE_NAME "DemoDevice"
#define EXAMPLE_DEVICE_SECRET "d68567cadd0bf3eeee5c3a1106512"
来生成上面需要的
char clientId[150];
char username[65];
char password[65];
阿里IODT平台提供了相应的生成函数
int aiotMqttSign(const char *productKey, const char *deviceName, const char *deviceSecret,
char clientId[150], char username[65], char password[65]);
至于:#define EXAMPLE_PRODUCT_KEY "a1ddsgdi0r"
这个参数是接入阿里IOT平台时,构成域名的一部分:a1ddsgdi0r.iot-as-mqtt.cn-shanghai.aliyuncs.com
顺便说明一下, 接入阿里IOT平台时, 使用443端口。
下面是从(https://www.jianshu.com/p/8b0291e8ee02)抄的图,把mqtt的不同QOS的消息传输过程讲的非常清楚;