Ejabberd源码解读-ejabberd_sm模块

本文详细探讨了ejabberd的会话管理模块ejabberd_sm,包括启动过程、会话的开启与关闭,以及路由机制。ejabberd_sm在初始化时与数据库交互,设置hook和命令,并在open_session和close_session过程中通过不同backends(如Mnesia、Redis、SQL)处理session。路由流程中,ejabberd_sm负责根据目标JID转发解析结果。
摘要由CSDN通过智能技术生成

ejabberd_sm是Ejabberd Session Manager的缩写,顾名思义是会话管理模块
ejabberd_sm进程在初始化时会进行一系列相关数据库(backends)操作,XMPP协议协商校验完成,ejabberd_c2s进程会调用ejabberd_sm:open_session/5方法,此时session会增加一条记录并存储该ejabberd_c2s进程pid,具体过程详细看以下流程

1 ejabberd_sm启动
查看ejabberd_app.erl文件,启动过程语句

%%%启动ms模块
ejabberd_sm:start()
start() ->
    ChildSpec = {?MODULE, {?MODULE, start_link, []},
         transient, 1000, worker, [?MODULE]},
    supervisor:start_child(ejabberd_sup, ChildSpec).
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

由ejabberd_sm:start/0可知,这里启动的是ejabberd_sup的一个子进程,然后调用ejabberd_sm:start_link/0启动一个gen_server进程,接下来调用init/1函数

init([]) ->
    lists:foreach(fun(Mod) -> Mod:init() end, get_sm_backends()),
    ets:new(sm_iqtable, [named_table]),
    lists:foreach(
      fun(Host) ->
          ejabberd_hooks:add(roster_in_subscription, Host,
                 ejabberd_sm, check_in_subscription, 20),
          ejabberd_hooks:add(offline_message_hook, Host,
                 ejabberd_sm, bounce_offline_message, 100),
          ejabberd_hooks:add(remove_user, Host,
                 ejabberd_sm, disconnect_removed_user, 100)
      end, ?MYHOSTS),
    ejabberd_commands:register_commands(get_commands_spec()),
    {
   ok, #state{}}.

init执行以下操作:
1 通过get_sm_backends获取session manage支持存储的后台方式,并一次调用模块init/0函数
(ejabberd_sm_mnesia,ejabberd_sm-redis,ejabberd_sql)
2 创建sm_qitable表
3 添加相关hook,并注册一系列命令(command)
乱入:
backends模块init/0函数主要都是进行数据库信息清理工作
以ejabberd_sm_mnesia模块为例
启动gen_server进程

-spec init() -> ok | {error, any()}.
init() ->
    case gen_server:start_link({local, ?MODULE}, ?MODULE, [], []) of
    {ok, _Pid} ->
        ok;
    Err ->
        Err
    end.

更新表格信息,创建相关表格

init([]) ->
    update_tables(),
    ejabberd_mnesia:create(?MODULE, session,
            [{ram_copies, [node()]},
             {attributes, record_info(fields, session)}]),
    ejabberd_mnesia:create(?MODULE, session_counter,
            [{ram_copies, [node()]},
             {attributes, record_info(fields, session_counter)}]),
    mnesia:add_table_index(session, usr),
    mnesia:add_table_index(session, us),
    mnesia:add_table_copy(session, node(), ram_copies),
    mnesia:add_table_copy(session_counter, node(), ram_copies),
    mnesia:subscribe(system),
    {ok, #state{}}.

session表格属性:sid, usr, us, priority, info
session表格项实例(一组会话)

{session,{
   {1484,189334,1},<0.14298.0>},
         {<<"admin">>,<<"localhost">>,<<"Psi+">>},
         {<<"admin">>,<<"localhost">>},
         50,
         [{
   ip,{
   {127,0,0,1},55204}},
          {conn,c2s},
          {auth_module,ejabberd_auth_mnesia}]}
{session,{
   {1484,189334,2},<0.14300.0>},
         {<<"test">>,<<"localhost">>,<<"Psi+">>},
         {<<"test">>,<<"localhost">>},
         50,
         [{
   ip,{
   {127,0,0,1},55206}},
          {conn,c2s},
          {auth_module,ejabberd_auth_mnesia}]}

update_tables()/0函数说明
更新表格并删除存留的presence和local_session信息

update_tables() ->
    %%%标准表格属性
    case catch mnesia:table_info(session, attributes) of
      [ur, user, node] -> mnesia:delete_table(session);
      [ur, user, pid] -> mnesia:delete_table(session);
      [usr, us, pid] -> mnesia:delete_table(session);
      [usr, us, sid, priority, info] -> mnesia:delete_table(session);
      [sid, usr, us, priority] ->
      mnesia:delete_table(session);
      [sid, usr, us, priority, info] -> ok;
      {
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值