ejabberd_router、ejabberd_router_multicast
ejabberd_router作为gen_server启动,作为系统的路由
对外提供注册路由、删除路由
初始化时创建route(mnesia)表,监控注册的路由进程
主要方法为do_route(OrigFrom, OrigTo, OrigPacket)方法
do_route(OrigFrom, OrigTo, OrigPacket) ->
?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket "
"~p~n",
[OrigFrom, OrigTo, OrigPacket]),
case ejabberd_hooks:run_fold(filter_packet,
{OrigFrom, OrigTo, OrigPacket}, [])
of
{From, To, Packet} ->
LDstDomain = To#jid.lserver,
case mnesia:dirty_read(route, LDstDomain) of
[] -> ejabberd_s2s:route(From, To, Packet);
[R] ->
Pid = R#route.pid,
if node(Pid) == node() ->
case R#route.local_hint of
{apply, Module, Function} ->
Module:Function(From, To, Packet);
_ -> Pid ! {route, From, To, Packet}
end;
is_pid(Pid) -> Pid ! {route, From, To, Packet};
true -> drop
end;
Rs ->
Value = case
ejabberd_config:get_local_option({domain_balancing,
LDstDomain}, fun(D) when is_atom(D) -> D end)
of
undefined -> now();
random -> now();
source -> jid:tolower(From);
destination -> jid:tolower(To);
bare_source ->
jid:remove_resource(jid:tolower(From));
bare_destination ->
jid:remove_resource(jid:tolower(To))
end,
case get_component_number(LDstDomain) of
undefined ->
case [R || R <- Rs, node(R#route.pid) == node()] of
[] ->
R = lists:nth(erlang:phash(Value, length(Rs)), Rs),
Pid = R#route.pid,
if is_pid(Pid) -> Pid ! {route, From, To, Packet};
true -> drop
end;
LRs ->
R = lists:nth(erlang:phash(Value, length(LRs)),
LRs),
Pid = R#route.pid,
case R#route.local_hint of
{apply, Module, Function} ->
Module:Function(From, To, Packet);
_ -> Pid ! {route, From, To, Packet}
end
end;
_ ->
SRs = lists:ukeysort(#route.local_hint, Rs),
R = lists:nth(erlang:phash(Value, length(SRs)), SRs),
Pid = R#route.pid,
if is_pid(Pid) -> Pid ! {route, From, To, Packet};
true -> drop
end
end
end;
drop -> ok
end.
在route表里面查找要发送域的路由信息,如果没有找到则利用ejabberd_s2s发送到别的节点查找,如果找到则:
调用进程注册的函数
-module(ejabberd_local). ejabberd_router:register_route(Host, {apply, ?MODULE, route}),
或者直接发送信息到注册的进程
-------------------------------------------------------------------------------------------------------
ejabberd_router_multicast作为gen_server启动,多播路由
对外提供注册删除路由
主要为do_route(From, Domain, Destinations, Packet)方法
首先到route_multicast(mnesia)表里面查找
若果找到则直接往注册的进程pid里面发送信息Pid ! {route_trusted, From, Destinations, Packet}
否则走普通的路由
do_route_normal(From, Destinations, Packet) ->
[ejabberd_router:route(From, To, Packet) || To <- Destinations].

浙公网安备 33010602011771号