MQTT实现智能家居------3、源码分析(超详细)

news/2025/2/24 12:41:09

一、连接服务器

1、初始化:

mqtt_log_init();是一个空函数,自己定义宏

client = mqtt_lease();//创建一个client结构体,从此以后client代表客户端

        platform_memory_alloc();//是一个分配内存的总函数,可以适用于Linux、FreeRTos等等

        mqtt_init();//分配完然后初始化一些信息,就比如说有MQTT的版本、保持心跳间隔等等很多

2、配置一下连接的信息:

        mqtt_set_host();//要去链接哪个服务器

        mqtt_set_port;//连接服务器端口

        .

        .

        等信息

3、开始连接

mqtt_connect();//开始连接

     mqtt_connec_with_results();//成功就调用它

        network_init();//网络初始化

        network_connect();//进行网络连接

                如果不考虑安全性

                nettype_tcp_connect();//进行TCP连接

                        platform_net_socket_connect();//最底层的设计硬件驱动

                        如果移植到Linux不需要改,如果是FreeRTos则需要大改(AT命令、串口操作)

二、创建线程

图一

接上面  

mqtt_connect();//开始连接

        mqtt_connec_with_results();//成功就调用它

                network_init();//网络初始化

                network_connect();//进行网络连接

                mqtt_send_packet();//图一中CONNECT请求连接

                mqtt_wait_packet();//图一中CONNECT确认请求连接

                pthread_create("标题", , name, c);//创建名为name一个线程,这里以mqtt_publish_thread为例:‘

三、发布消息

mqtt_publish_thread();//构造一个消息结构体,有数据长度payloadlen和上报的数据保存在*payload

        1、构造消息

        mqtt_message_t         msg;

        

        memset(&msg, 0, sizeof(msg));

        msg.payload = (void *)buf;

        msg.payloadlen = xxx;

        mqtt_publish();

                2、根据MQTT协议将数据有序化

                MQTTSerialize_publish();//排序,将数据序列化

                3、根据平台相关的函数发送数据包

                mqtt_send_packet();//发送数据包

                        network_write();

                         nettype_tcp_write();

                                platform_net_socket_write_timeout();//最后的底层 

四、订阅消息(检测消息来并且接收)

mqtt_subscrib(client, "topic1", QOS0, topic1_handler); //订阅 "topic1"这个主题的消息,通过topic1_handler这个函数处理消息。

         topic1_handler()//控制这个消息目的,比如去干某些事情

大体框架:

        线程{

while(1)

{

        读网络数据;

        if(是发布消息)

        {

                分辨主题;

                调用对应函数;
        }
}

}

mqtt_subscrib(client, "topic1", QOS0, topic1_handler);

        1、创建一个结构体

topic_filter:指向一个字符串,表示哪个主题。

handler:一个函数指针

        2、将数据放入结构体

   mqtt_msg_handler_create; //

        platform_memory_alloc();//分配一块内存

        将数据传给结构体;

        3、记录下来,存在链表list中

    mqtt_ack_list_record();//放入某个链表

       目的是以后在遇到这个主题的消息时候直接调用链表存的函数。

五、核心线程

mqtt_connect();//开始连接

        platform_thread_init("mqtt_yield_thread", mqtt_yield_thread, );//连接成功后创建核心线程

                mqtt_yield_thread();

                         mqtt_yield();//1、读包处理包    2、保持心跳(是不是发ping信号)3、处理错误

                                mqtt_packet_handle;

                                        1)读包处理包

                                        mqtt_read_packet;先读包

                                        switch(){//处理

                                                         case0: 没收到包

                                                        case x:处理某个包

                                                       }

                                        2)保持心跳

                                        3)处理错误,重连

具体如何处理(以PUBLISH为例子):

        mqtt_publish_packet_handle();//处理包函数

                MQTTDeserialize_publish();//解析包

                mqtt_deliver_message();//传送消息

                        mqtt_get_msg_handler(c, 主题);//根据主题在链表找出handler,调用handler对应处理函数。

      

六、总结一下

                      先连接服务器

                      然后创建发布线程,成功以后创建核心线程,读包处理包;

                       然后订阅消息,创建每个消息的处理函数,将订阅的消息存在链表;

                        读包处理包:将包的信息读取出来对比是否订阅,如果订阅就调用对应函数;


http://www.niftyadmin.cn/n/5864330.html

相关文章

[oAuth2授权]Web前端+NodeCoze API Web后端程序+Coze授权服务器工作流程架构流程图详解

嗯,用户之前已经了解了如何使用React和Node.js结合Coze API实现OAuth2授权,现在他们具体想实现的是在Web应用中,当用户点击一个按钮(比如“和Bot对话”)时,触发授权流程,重定向到Coze的授权服务器获取code。用户还提供了一个具体的cURL请求示例,展示了如何通过302重定向…

鸿蒙学习-

鸿蒙数据传值 //* 传值 //* State /**State创建一个响应式的数据,但不是所有的更改都会引起刷新,只有被框架观察到的修改才会被刷新UI* 1. 基本数据类型如 number string boolean等值的变化修改* 2. Object类型,只会观察到第一层的数据变化或…

Redis面试宝典【刷题系列】

文章目录 一、什么是Redis?二、Redis相比Memcached有哪些优势?三、Redis支持的数据类型有哪些?四、Redis的主要消耗的物理资源是什么?五、Redis的全称是什么?六、Redis有哪些数据淘汰策略?七、为什么Redis需…

从底层驱动到 OpenCV:深入解析 Linux 摄像头完整技术栈

1. 引言 在嵌入式 Linux(如树莓派、NXP i.MX 8M Plus)上,摄像头数据的完整处理链涉及多个层次: 底层驱动层:设备树 (Device Tree)、MIPI CSI-2 协议、V4L2 (Video4Linux2)中间件层:libcamera(…

Ollama Linux 部署指南

文章来源:Linux 部署文档 -- Ollama 中文文档|Ollama官方文档 安装 要安装 Ollama,请运行以下命令: curl -fsSL https://ollama.com/install.sh | sh手动安装 [!注意] 如果要从以前的版本升级,则应使用sudo rm -rf /usr/lib/ol…

百度首页上线 DeepSeek 入口,免费使用

大家好,我是小悟。 百度首页正式上线了 DeepSeek 入口,这一重磅消息瞬间在技术圈掀起了惊涛骇浪,各大平台都被刷爆了屏。 百度这次可太给力了,PC 端开放仅 1 小时,就有超千万人涌入体验。这速度,简直比火…

计算机网络常考大题

运输层的主要功能 运输层为应用进程之间提供端到端的逻辑通信。 运输层还要对收到的报文进行差错检测。 运输层需要有两种不同的运输协议,即面向连接的 TCP 和无连接的 UDP 传输控制协议 TCP 概述 TCP 是面向连接的运输层协议。 每一条 TCP 连接只能有两个端点…

python-静态方法和类方法

Java之类的编程语言还带有静态方法,Python类也拥有与静态方法明确对应的方法。此外,Python还拥有类方法,要比静态方法更高级一些。 静态方法与Java一样,即便没有创建类的实例,静态方法也是可以调用的,当然…