Ejabberd源码解读-ejabberd_router模块

概述
ejabberd_router是ejabberd项目消息传递的重要路由模块,属于路由总线,消息通过socket传递到达ejabberd_receiver模块解析处理后,传递给ejabberd_c2s逻辑处理模块,调用ejabberd_router:route/3进行路由分发,然后再区分不同情况,选择合适的二级路由中转,最后调用ejabberd_sm:route/3分发到目的用户
详述
路由章节其实并不局限于ejabberd_router模块,涉及到多个模块,以下将根据消息路由流程,逐步查看相关模块
ejabberd_c2s逻辑模块
1 Sever=>Client handle_info/4(处理来自ejabberd_sm:route/3的消息)
handle_info/4处理ejabberd_sm模块定义类型broadcast_data()

-type broadcast_data() ::
        {rebind, pid(), binary()} | %%% ejabberd_c2s
        {item, ljid(), mod_roster:subscription()} | %%% mod_roster/mod_shared_roster
        {exit, binary()} | %%% mod_roster/mod_shared_roster
        {privacy_list, mod_privacy:userlist(), binary()} | %%% mod_privacy
        {blocking, unblock_all | {block | unblock, [ljid()]}}. %%% mod_blocking
handle_info({route, _From, _To, {broadcast, Data}},
            StateName, StateData) ->
    ?DEBUG("broadcast~n~p~n", [Data]),
    case Data of
    %%%更新发送花名册
    %%%订阅from_返回最后出席信息(未更新)
    %%%取消from_返回unavailable出席信息==>(具体查看roster_change/3)
        {item, IJID, ISubscription} ->
            fsm_next_state(StateName,
                           roster_change(IJID, ISubscription, StateData));
    %%%发送错误信息        
    {exit, Reason} ->
            Lang = StateData#state.lang,
            send_element(StateData, xmpp:serr_conflict(Reason, Lang)),
            {stop, normal, StateData};
    %%%更新发送黑名单
        {privacy_list, PrivList, PrivListName} ->
            case ejabberd_hooks:run_fold(privacy_updated_list,
                                         StateData#state.server,
                                         false,
                                         [StateData#state.privacy_list,
                                          PrivList]) of
                false ->
                    fsm_next_state(StateName, StateData);
                NewPL ->
            PrivPushIQ =
            #iq{type = set,
                from = jid:remove_resource(StateData#state.jid),
                to = StateData#state.jid,
                id = <<"push", (randoms:get_string())/binary>>,
                sub_els = [#privacy_query{
   
                      lists = [#privacy_list{
   
                              name = PrivListName}]}]},
                    NewState = send_stanza(StateData, PrivPushIQ),
                    fsm_next_state(StateName,
                                   NewState#state{privacy_list = NewPL})
            end;
    %%%通讯阻止
        {blocking, What} ->
            NewState = route_blocking(What, StateData),
            fsm_next_state(StateName, NewState);
        _ ->
            fsm_next_state(StateName, StateData)
    end;

handle_info/4处理常规消息

handle_info({route, From, To, Packet}, StateName, StateData) when ?is_stanza(Packet) ->
    %%%Pass==false,无需做后续处理(消息发送完成或已发送报错信息),若Pass==true,路由信息
    {
  Pass, NewState} =
    case Packet of
        %%%出席信息
        #presence{type = T} ->
        State = ejabberd_hooks:run_fold(c2s_presence_in,
                        StateData#state.server,
                        StateData,
                        [{
  From, To, Packet}]),
        case T of
         %%%State.pres_f 出席from(“某用户订阅了我的出席”) 
         %%%State.pres_t 出席to(“我订阅了某用户出席”)
           %%%State.pres_a 出席(all) 
           %%%probe出席调查
            probe ->
            LFrom = jid:tolower(From),
            LBFrom = jid:remove_resource(LFrom),
            NewStateData =
                case (?SETS):is_element(LFrom, State#state.pres_a)
                orelse (?SETS):is_element(LBFrom, State#state.pres_a) of
                true -> State;
                false ->
                    case (?SETS):is_element(LFrom, State#state.pres_f) of
                    true ->
                        A = (?SETS):add_element(LFrom, State#state.pres_a),
                        State#state{pres_a = A};
                    false ->
                        case (?SETS):is_element(LBFrom, State#state.pres_f) of
                        true ->
                            A = (?SETS):add_element(LBFrom, State#state.pres_a),
                            State#state{pres_a = A};
                        false ->
                            State
                        end
                    end
                end,
            %%%直接回复probe请求-包含最后出席信息和时间戳(若源节点(from)为自身,则不做处理)
            process_presence_probe(From, To, NewStateData),
            {
  false, NewStateData};
            error ->
            NewA = ?SETS:del_element(jid:tolower(From), State#state.pres_a),
            {
  true, State#state{pres_a = NewA}};
            subscribe ->
            SRes = is_privacy_allow(State, From, To, Packet, in),
            {
  SRes, State};
            subscribed ->
            SRes = is_privacy_allow(State, From, To, Packet, in),
            {
  SRes, State};
            unsubscribe ->
            SRes = is_privacy_allow(State, From, To, Packet, in),
            {
  SRes, State};
            unsubscribed ->
            SRes = is_privacy_allow(State, From, To, Packet, in),
            {
  SRes, State};
            _ ->
            case privacy_check_packet(State, From, To, Packet, in) of
                allow ->
                LFrom = jid:tolower(From),
                LBFrom = jid:remove_resource(LFrom),
                case (?SETS):is_element(LFrom, State#state.pres_a)
                    orelse (?SETS):is_element(LBFrom, State#state.pres_a) of
                    true ->
                    {
  true, State};
                    false ->
                    case (?SETS):is_element(LFrom, State#state.pres_f) of
                        true ->
                        A = (?SETS):add_element(LFrom, State#state.pres_a),
                        {
  true, State#state{pres_a = A}};
                        false ->
                        case (?SETS):is_element(LBFrom,
                                    State#state.pres_f) of
                            true ->
                            A
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值