热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我的mqtt协议和emqttd开源项目个人理解(3)客户端publish消息QoS==0的源码分析

学习mqtt协议和emqttd开源项目http:emqtt.comemqttd源码版本号是v1.1.3。http:emqtt.comdownloads1113源码写得比较绕

学习mqtt协议和emqttd开源项目http://emqtt.com/

emqttd源码版本号是v1.1.3。http://emqtt.com/downloads/1113


源码写得比较绕,需要经过以下模块的调用,入口是emqttd_client模块,handle_info函数负责接收socket的数据:

(注意:gen_server:call是同步调用,cast是异步。call对应的是handle_info,cast对应的是handle_cast。)


1、-module(emqttd_client).

handle_info({inet_async, _Sock, _Ref, {ok, Data}}, State) ->
received(Bytes, State = #client_state{parser_fun = ParserFun,packet_opts = PacketOpts,proto_state = ProtoState}) ->


2、-module(emqttd_parser).

parse(<>, {none, Limit}) ->

3、-module(emqttd_protocol).

解析PUBLISH消息

received(Packet &#61; ?PACKET(_Type), State) ->
process(Packet &#61; ?PUBLISH_PACKET(_Qos, Topic, _PacketId, _Payload), State) ->
publish(Packet &#61; ?PUBLISH_PACKET(?QOS_0, _PacketId),#proto_state{client_id &#61; ClientId, username &#61; Username, session &#61; Session}) ->


4、-module(emqttd_session).

publish(_SessPid, Msg &#61; #mqtt_message{qos &#61; ?QOS_0}) ->

5、-module(emqttd).

publish(Msg) when is_record(Msg, mqtt_message) ->

6、-module(emqttd_server).

publish(Msg &#61; #mqtt_message{from &#61; From}) ->

7、-module(emqttd_pubsub).

这里考虑了本机节点和集群节点的情况

publish(Topic, Msg) ->lists:foreach(fun(#mqtt_route{topic &#61; To, node &#61; Node}) when Node &#61;:&#61; node() ->?MODULE:dispatch(To, Msg);(#mqtt_route{topic &#61; To, node &#61; Node}) ->rpc:cast(Node, ?MODULE, dispatch, [To, Msg])end, emqttd_router:lookup(Topic)).


dispatch(Topic, Msg) ->
SubPid ! {dispatch, Topic, Msg};


8、-module(emqttd_session).

handle_info({dispatch, Topic, Msg}, Session &#61; #session{subscriptions &#61; Subscriptions})when is_record(Msg, mqtt_message) ->这里会区分Client是否在线离线&#xff0c;还有CleanSession&#61;0/QoS&#61;1,2的情况&#xff0c;需要存储离线消息。

%% Queue message if client disconnected
dispatch(Msg, Session &#61; #session{client_pid &#61; undefined, message_queue &#61; Q}) ->hibernate(Session#session{message_queue &#61; emqttd_mqueue:in(Msg, Q)});%% Deliver qos0 message directly to client
dispatch(Msg &#61; #mqtt_message{qos &#61; ?QOS0}, Session &#61; #session{client_pid &#61; ClientPid}) ->ClientPid ! {deliver, Msg},hibernate(Session);dispatch(Msg &#61; #mqtt_message{qos &#61; QoS}, Session &#61; #session{message_queue &#61; MsgQ})when QoS &#61;:&#61; ?QOS1 orelse QoS &#61;:&#61; ?QOS2 ->case check_inflight(Session) oftrue ->noreply(deliver(Msg, Session));false ->hibernate(Session#session{message_queue &#61; emqttd_mqueue:in(Msg, MsgQ)})end.


9、-module(emqttd_client).

handle_info({deliver, Message}, State) ->with_proto_state(fun(ProtoState) ->emqttd_protocol:send(Message, ProtoState)end, State);

10、-module(emqttd_protocol).

send(Packet, State &#61; #proto_state{sendfun &#61; SendFun})when is_record(Packet, mqtt_packet) ->


推荐阅读
  • Kubernetes Services详解
    本文深入探讨了Kubernetes中的服务(Services)概念,解释了如何通过Services实现Pods之间的稳定通信,以及如何管理没有选择器的服务。 ... [详细]
  • C#爬虫Fiddler插件开发自动生成代码
    哈喽^_^一般我们在编写网页爬虫的时候经常会使用到Fiddler这个工具来分析http包,而且通常并不是分析一个包就够了的,所以为了把更多的时间放在分析http包上,自动化生成 ... [详细]
  • Activity跳转动画 无缝衔接
    Activity跳转动画 无缝衔接 ... [详细]
  • Cadence SPB 16.5 安装指南与注意事项
    本文提供了详细的 Cadence SPB 16.5 安装步骤,包括环境配置、安装过程中的关键步骤以及常见问题的解决方案。适合初次安装或遇到问题的技术人员参考。 ... [详细]
  • 本文档提供了详细的MySQL安装步骤,包括解压安装文件、选择安装类型、配置MySQL服务以及设置管理员密码等关键环节,帮助用户顺利完成MySQL的安装。 ... [详细]
  • 深入解析轻量级数据库 SQL Server Express LocalDB
    本文详细介绍了 SQL Server Express LocalDB,这是一种轻量级的本地 T-SQL 数据库解决方案,特别适合开发环境使用。文章还探讨了 LocalDB 与其他轻量级数据库的对比,并提供了安装和连接 LocalDB 的步骤。 ... [详细]
  • 本文介绍了进程的基本概念及其在操作系统中的重要性,探讨了进程与程序的区别,以及如何通过多进程实现并发和并行。文章还详细讲解了Python中的multiprocessing模块,包括Process类的使用方法、进程间的同步与异步调用、阻塞与非阻塞操作,并通过实例演示了进程池的应用。 ... [详细]
  • 本文详细介绍了如何在 EasyUI 框架中实现 DataGrid 组件的分页功能,包括配置方法和常见问题的解决方案。 ... [详细]
  • 工作中频繁在不同Linux服务器之间切换时,频繁输入密码不仅耗时还影响效率。本文介绍如何通过设置SSH密钥认证,简化登录流程,提高工作效率。 ... [详细]
  • Kubernetes 实践指南:初次体验
    本文介绍了如何通过官方提供的简易示例,快速上手 Kubernetes (K8S),并深入理解其核心概念和操作流程。 ... [详细]
  • 前端技术分享——利用Canvas绘制鼠标轨迹
    作为一名前端开发者,我已经积累了Vue、React、正则表达式、算法以及小程序等方面的技能,但Canvas一直是我的盲区。因此,我在2018年为自己设定了一个新的学习目标:掌握Canvas,特别是如何使用它来创建CSS3难以实现的动态效果。 ... [详细]
  • 本文详细介绍了PHP中的几种超全局变量,包括$GLOBAL、$_SERVER、$_POST、$_GET等,并探讨了AJAX的工作原理及其优缺点。通过具体示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 本文详细介绍了在PHP中如何获取和处理HTTP头部信息,包括通过cURL获取请求头信息、使用header函数发送响应头以及获取客户端HTTP头部的方法。同时,还探讨了PHP中$_SERVER变量的使用,以获取客户端和服务器的相关信息。 ... [详细]
  • 页面预渲染适用于主要包含静态内容的页面。对于依赖大量API调用的动态页面,建议采用SSR(服务器端渲染),如Nuxt等框架。更多优化策略可参见:https://github.com/HaoChuan9421/vue-cli3-optimization ... [详细]
  • 本文由chszs撰写,详细介绍了Apache Mina框架的核心开发流程及自定义协议处理方法。文章涵盖从创建IoService实例到协议编解码的具体步骤,适合希望深入了解Mina框架应用的开发者。 ... [详细]
author-avatar
Jaaaaasonnv_116
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有