MQTT框架和使用-1
https://developer.aliyun.com/article/1507967
3. kawaii-mqtt源码分析
3.1 使用
几条代码使用MQTT:
void my_message_handler_t(void* client, message_data_t* msg) { } int main(void) { int err; mqtt_client_t *client = NULL; err = mqtt_connect(client); err = mqtt_subscribe(client, "100ask-topic", QOS0, my_message_handler_t); while (1); }
从上述代码中,提2个问题:
答案:
3.2 kawaii-mqtt内部实现
3.2.1 主要代码
kawaii-mqtt内部处理都是使用mqtt_yield_thread线程来处理:
主要函数是mqtt_yield:
mqtt_yield里的核心函数是对数据包的处理:mqtt_packet_handle
3.2.2 处理函数记录在链表里
mqtt_client结构体里有2个链表:
MQTT Client向Broker发出某些数据包时,期待得到回应(ACK):会启动一个定时器。如果定时器超时表示没有收到ACK:
- 要么重发
- 要么出错
- 对于ACK包,一般无需提供处理函数
要订阅某个主题时,MQTT Client会发出SUBCRIBE包,期待得到回应的数据包:SUBACK包。代码如下:
mqtt_subscribe msg_handler = mqtt_msg_handler_create(topic_filter, qos, handler); rc = mqtt_ack_list_record(c, SUBACK, packet_id, len, msg_handler); /* create a ack handler node */ ack_handler = mqtt_ack_handler_create(c, type, packet_id, payload_len, handler); platform_timer_cutdown(&ack_handler->timer, c->mqtt_cmd_timeout); mqtt_list_add_tail(&ack_handler->list, &c->mqtt_ack_handler_list);
如果在指定时间里没有收到SUBACK包,那么就会在mqtt_ack_handler_list中删除该handler。
如果收到队列SUBACK包,那么要做两件事:
- 在mqtt_ack_handler_list中删除该handler
- 把该handler放到mqtt_msg_handler_list中:以后收到PUBLISH数据包时这个handler被调用
3.2.3 流程图