ejabberd源码流程梳理
ejabberd的工程主要通过ejabberd.app 组织起来
ejabberd.erl :
application:start(ejabberd).
ejabberd_app.erl:
Mod:start(normal, _Args); 该函数中启动ejabberd_listener:start_listeners()
ejabberd_listener.erl
通过 conf 得到<!---->ejabberd_c2s,
开始listen
如果有连接,accpet之后
<!---->ejabberd_socket:start(Module, gen_tcp, Socket, Opts)
Receiver=ejabberd_receiver:start(
Socket,SockMod,none,MaxStanzaSize),
ejabberd_receiver.erl
ejabberd_receiver是一个gen_server进程(behaviour),
receiver 收到数据(handle_info)发送到xml_stream.
xml_stream解析数据后发送到c2s状态机.
ejabber_c2s.erl
是一个gen_fsm(有限状态机),维护一系列client和server之间的状态。gen_fsm的状态改变是由gen_fsm:send_event(FsmRef,Event)触发的。在ejabberd里,ejabberd_receiver通过xml_stream把事件和xml发送至ejabber_c2s改变其状态。
ejabber_c2s有限状态机的初始状态是wait_for_stream,其余的状态有:
wait_for_auth,wait_for_feature_request,wait_for_sasl_response,wait_for_bind,wait_for_session,session_established
ejabberd官方文档中提到的那些关于xmpp收到的事件的hook,就是在c2s中实现的。
c2s中调用ejabberd_hooks:run_fold()来运行相应的hook。
1.Presence消息流程
用户登陆过程中:
在c2s的waitforsession中调用
{Fs, Ts} = ejabberd_hooks:run_fold(
roster_get_subscription_lists,
StateData#state.server,
{[], []},
[U, StateData#state.server]),
获取from、to好友列表,分别置入state. pres_f和state. pres_t中。
客户端登陆成功后,给服务器发送
<presence id="B0DjG-12">
<status>在线</status>
<priority>1</priority>
</presence>
该presence没有目的地址(to)。
服务端收到该消息在c2s的session_established2中处理,
调用presence_update(FromJID, PresenceEl,StateData)
èpresence_broadcast_first(From, NewStateData, Packet);
(1) 给state.pres_t中每个成员发送probe;
(2)给state.pres_f中每个成员发送presence
2.添加好友流程
以Lihengz 添加 admin 好友为例
下列状态值中第一项为“订阅(subscription)”,第二项为“挂起(ask)”
Lihengz的状态变化为 :out_state_change(none,none, subscribe) -> {none, out};
Admin的状态变化为:in_state_change(none,none, subscribe) -> {none, in};
Admin接受请求后,状态变化:out_state_change(none,in, subscribed) -> {from, none};
Lihengz状态变化:in_state_change(none,out, subscribed) -> {to, none};
如果admin也加lihengz为好友:
admin状态变化:out_state_change(from,none, subscribe) -> {from, out};
lihengz状态变化: in_state_change(to, none, subscribe) -> {to, in};
lihengz接受请求后,状态变化:out_state_change(to, in, subscribed) -> {both, none};
admin状态变化:in_state_change(from,out, subscribed) -> {both, none};
3,在服务器上添加通讯录
在服务器上为mine添加mine1为好友(mine1未设置自动添加好友)
mine客户端会收到如下消息:
<iq id="push3140513066"to="mine@xmppserver/Spark 2.6.3" from="mine@xmppserver"type="set">
<query xmlns="jabber:iq:roster">
<item jid="mine1@xmppserver" subscription="none"ask="subscribe"/>
</query>
</iq>
如果mine1拒绝请求,mine客户端就收不到后续消息了。Roster表中一直维持挂起状态。
如果mine1设置为自动添加好友,mine客户端会收到:
<iq id="push3548743800"to="mine@xmppserver/Spark 2.6.3" from="mine@xmppserver"type="set">
<query xmlns="jabber:iq:roster">
<item jid="mine1@xmppserver" subscription="both"/>
</query>
</iq>
from: http://www.cnblogs.com/unqiang/p/4402418.html
ejabberd源码流程梳理的更多相关文章
- Eureka服务端源码流程梳理
一.简述 spring cloud三步走,一导包,二依赖,三配置为我们简化了太多东西,以至于很多东西知其然不知其所以然,了解底层实现之后对于一些问题我们也可以快速的定位问题所在. spring clo ...
- Eureka客户端源码流程梳理
前面梳理了Eureka服务端的流程,现在整理下客户端的流程. 1.在这个包(spring-cloud-netflix-eureka-client)里面寻找客户端启动入口相关配置,关键配置文件sprin ...
- ClickHouse源码笔记5:聚合函数的源码再梳理
笔者在源码笔记1之中分析过ClickHouse的聚合函数的实现,但是对于各个接口函数的实际如何共同工作的源码,回头看并没有那么明晰,主要原因是没有结合Aggregator的类来一起分析聚合函数的是如果 ...
- Flask 源码流程,上下文管理
源码流程 创建对象 from flask import Flask """ 1 实例化对象 app """ app = Flask(__na ...
- ES6.3.2 index操作源码流程
ES 6.3.2 index 操作源码流程 client 发送请求 TransportBulkAction#doExecute(Task,BulkRequest,listener) 解析请求,是否要自 ...
- django-admin的源码流程
一.admin的源码流程 首先可以确定的是:路由关系一定对应一个视图函数 a.当点击运行的时候,会先找到每一个app中的admin.py文件,并执行 b.执行urls.py admin.site是什么 ...
- Django session 源码流程
流程 Django session源码流程 首先执行的是SessionMiddleware的init方法 import_module(settings.SESSION_ENGINE) 导入了一个 dj ...
- rest_framework解析器组件源码流程
rest_framework解析器组件源码流程 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数 ...
- 【转】ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解
原文地址:http://blog.csdn.net/a396901990/article/details/36475213 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量—— ...
随机推荐
- 【iOS】init,loadView,viewDidLoad加载关系
一.loadView 永远不要主动调用这个函数.view controller会在view的property被请求并且当前view值为nil时调用这个函数.如果你手动创建view,你应该重载这个函数. ...
- c#教程之事件处理函数的参数
事件处理函数一般有两个参数,第一个参数(object sender)为产生该事件的对象的属性Name的值,例如上例单击标题为红色的按钮,第一个参数sender的值为button1.如上例标题为红色的按 ...
- 类的本质、description方法、SEL、NSLog输出增强
一.类的本质 1.类也是个对象 其实类也是一个对象,是Class类型的对象,简称“类对象” Class类型的定义 typedef struct objc_class *Class; 类名就代表着类对象 ...
- ITaCS Change Password web part
http://changepassword.codeplex.com/ A webpart is used to change your sharepoint AD password.
- python总字符串
前面我们讲解了什么是字符串.字符串可以用''或者""括起来表示. 如果字符串本身包含'怎么办?比如我们要表示字符串 I'm OK ,这时,可以用" "括起来表示 ...
- python学习笔记7(使用字符串)
一.字符串格式化,在%左侧放置一个字符串,右侧放置希望格式化的值. >>> format = 'Hello,%s,%s enough for ya?' >>> va ...
- 如何修改SVN中的用户名和密码
删除掉C:\Users\Administrator\Application Data\Subversion\auth\svn.simple文件夹下的文件即可.再次访问时,会弹出要求输入用户名和密码. ...
- Elasticsearch搜索类型(query type)详解
关于我,邯郸人. 对这类话题感兴趣?欢迎发送邮件至donlianli@126.com 请支持原创http://www.cnblogs.com/donlianli/p/3857500.html e ...
- 1023: [SHOI2008]cactus仙人掌图 - BZOJ
Description如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路 ...
- What we learned in Seoul with AlphaGo
What we learned in Seoul with AlphaGo March 16, 2016 Go isn’t just a game—it’s a living, breathing c ...