zoukankan      html  css  js  c++  java
  • ejabberd分析(五)+订阅/添加好友


    模块ejabberd_c2s中,状态为session_established2。

    用户发送iq set 消息到服务器

    <iq id="M8QF3-52" type="set"><query xmlns="jabber:iq:roster"><item jid="1555215557@kinglong" name="1555215557"><group>Friends</group></item></query></iq>

    服务器端匹配到

    上面这段代码需要注意ToJID的解析,发送给服务器的消息一般是默认不带to 属性的,这种情况下会自动将to 补上(这关系到包的路由)。

    ejabberd_hooks:run(user_send_packet   会记录用户发送的消息到日志。

    check_privacy_route 中对权限进行效验,通过后调用ejabberd_router:route(FromRoute, To, Packet) 进行路由。

    在ejabberd_router:route中调用do_route/3:

    先用包过滤模块进行过滤,通过后在路由表中查找路由到的模块的Pid:

    注:此处会以LDstDomain = To#jid.lserver, 去router表查找是交由本地处理,还是交由其他server 处理。

    在模块ejabberd_local 中使用ejabberd_router:register_route(Host, {apply, ?MODULE, route}) 对当前domain进行了登记,所以会路由到此模块,并调用相应的route函数。

    在ejabberd_local:route/3中调用do_route(From, To, Packet)。

    客户端发送的iq消息初始to为空,但系统已自动补上ToJID(参见前面的说明),资源也为空的 iq,所以会路由到ejabberd_sm:route/3

    也就是说对于那些在session_established 之后发送的消息都会交由ejabberd_sm去路由。

    在ejabberd_sm中由do_route/3 来处理:

    ejabberd_sm 中有一张 sm_iqtable  里面记录了各个命名空间的消息最终由那个模块进行处理。

    ejabberd_sm 是一个gen_server 当调用register_iq_handler 接口时会向sm_iqtable 插入记录。

    而这些命名空间处理模块的登记是由gen_iq_handler 模块的add_iq_handler/6 来进行的。

    jabber:iq:roster 定义的宏为NS_ROSTER,我们在源码目录下查找此命名空间是由哪个模块调用的注册:



    在mod_roster:start/2 中有如下代码:


    可以看出mod_roster模块将自身的process_iq 函数在ejabberd_sm中注册为了jabber:iq:roster 命名空间的处理方法。

    process_iq中针对发送到本地的iq调用process_local_iq/3:


    这里会对针对iq 的 type 进行不同处理,我们目前跟踪的是<iq id="M8QF3-52" type="set">

     在process_iq_set 中会遍历每一item子项调用process_item_set/3 进行处理:
      remove ->mnesia:delete({roster, {LUser, LServer, LJID}});
     %%否则添加
    _ ->mnesia:write(Item2)end,
    %% If the item exist in shared roster, take the%% subscription information from there:
    Item3 = ejabberd_hooks:run_fold(roster_process_item,LServer, Item2, [LServer]),
    case roster_version_on_db(LServer)
    oftrue -> mnesia:write(#roster_version{us = {LUser, LServer}, version = sha:sha(term_to_binary(now()))});
    false -> okend,{Item, Item3}end,
    case mnesia:transaction(F)
    of{atomic, {OldItem, Item}} -> push_item(User, LServer, To, Item),
    case Item#roster.subscription
    ofremove -> send_unsubscribing_presence(From, OldItem),
    ok;_ -> ok end;
    E -> ?DEBUG("ROSTER: roster item set error: ~p~n", [E]), ok end end;
    
    

    
    
    以上就是一条添加/订阅 好友的iq 消息在ejabberd 中从接收到最终写入到数据库所经过的路径。








    
    
  • 相关阅读:
    C puzzles详解【51-57题】
    C puzzles详解【46-50题】
    C puzzles详解【38-45题】
    C puzzles详解【34-37题】
    C puzzles详解【31-33题】
    C puzzles详解【26-30题】
    C puzzles详解【21-25题】
    C puzzles详解【16-20题】
    使用C++模板实现栈的求最小值功能
    模拟求幂运算,考虑的已经很周全了
  • 原文地址:https://www.cnblogs.com/yjl49/p/2371953.html
Copyright © 2011-2022 走看看