zoukankan      html  css  js  c++  java
  • 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>

  • 相关阅读:
    Linux 为linux enterprises 6安装图形桌面教程
    loadrunner 结果分析-loadrunner结果分析
    python 全栈开发,Day91(Vue实例的生命周期,组件间通信之中央事件总线bus,Vue Router,vue-cli 工具)
    python 全栈开发,Day90(Vue组件,前端开发工具包)
    python 全栈开发,Day89(sorted面试题,Pycharm配置支持vue语法,Vue基础语法,小清单练习)
    python 全栈开发,Day88(csrf_exempt,ES6 快速入门,Vue)
    python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)
    python 全栈开发,Day85(Git补充,随机生成图片验证码)
    python 全栈开发,Day84(django请求生命周期,FBV和CBV,ORM拾遗,Git)
    python 全栈开发,Day83(博客系统子评论,后台管理,富文本编辑器kindeditor,bs4模块)
  • 原文地址:https://www.cnblogs.com/unqiang/p/4402418.html
Copyright © 2011-2022 走看看