ejabberd内部模块可以通过一个XMPP名称(-define(PROCNAME, ejabberd_mod_echo).
),添加自身到服务器的路由表中,这些模块被称为服务
,服务模块必须同时实现gen_server
和gen_mod
行为
例子
mod_echo.erl是一个使用路由机制的例子.
API
1
| ejabberd_router:register_route(Host)
ejabberd_router:unregister_route(Host),
* Host = string()
|
gen_server API
下面上个函数用作模块的API
1
| start_link(Host, Opts) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
|
1
| start(Host, Opts) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
ChildSpec = {Proc,{?MODULE, start_link, [Host, Opts]}, temporary, 1000, worker, [?MODULE]},
supervisor:start_child(ejabberd_sup, ChildSpec).
|
1
| stop(Host) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
gen_server:call(Proc, stop),
supervisor:terminate_child(ejabberd_sup, Proc),
supervisor:delete_child(ejabberd_sup, Proc).
|
gen_server 回调
下面的函数必须定义并导出.
1
| init([Host, Opts]) -> {ok, State} |
{ok, State, Timeout} |
ignore |
{stop, Reason}
|
1
| handle_info(Info, State) -> {noreply, State} |
{noreply, State, Timeout} |
{stop, Reason, State}
* Info = {route, From, To, Packet}
* To = From = #jid (see jlib core module)
* Packet = {xmlelement, Name, Attrs, SubEl}
|
1
| terminate(Reason, State) -> void()
|
1
| handle_call(stop, _From, State) -> {stop, normal, ok, State}.
|
1
| handle_cast(_Msg, State) -> {noreply, State}.
|
1
| code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
init
函数用于初始化模块.Host
为模块所在虚拟主机名称,Opts
为在配置文件中设置的模块选项,这些选项可以通过gen_mod:get_opt/3函数获取.ejabberd_router:register_route/1函数在init
回调中执行.
terminate/2
用于停止模块. ejabberd_router:unregister_route
函数在此回调中被调用.
handle_info/2
用于获取发送给该模块的XMPP包. ejabberd_router:route/1用于对包进行重新路由.
All other callbacks can be written as shown above.