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;
{