Erlang 如何接收发送到在gen_服务器内运行的PID的消息
我有一台ejabberd服务器Erlang 如何接收发送到在gen_服务器内运行的PID的消息,erlang,ejabberd,erlang-supervisor,ejabberd-module,Erlang,Ejabberd,Erlang Supervisor,Ejabberd Module,我有一台ejabberd服务器 我有一个自定义模块,my_apns_module.erl,由ejabberd服务器运行,如下所示: start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ?GEN_SERVER:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host
my_apns_module.erl
,由ejabberd服务器运行,如下所示:
start_link(Host, Opts) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
?GEN_SERVER:start_link({local, Proc}, ?MODULE,
[Host, Opts], []).
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).
stop(Host) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
?GEN_SERVER:call(Proc, stop),
supervisor:delete_child(ejabberd_sup, Proc),
ok.
init([Host, _Opts]) ->
...
handle_call(stop, _From, State) ->
{stop, normal, ok, State}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(#offline_msg{us = _UserServer,
from = From, to = To, packet = Packet} = _Msg, State) ->
...
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, State) ->
Host = State#state.host,
ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
handle_info({reconnecting, ServerPid}=Msg, State) ->
%%do something here, like log Msg or change State;
handl_info({connection_up, ServerPid}=Msg, State) ->
%%do something here, like log Msg or change State;
handle_info(#offline_msg{us = _UserServer,
from = From, to = To, packet = Packet} = _Msg, State) ->
%%do something.
init([Host, _Opts]) ->
spawn(?MODULE, start_apns, []),
...
start_apns() ->
apns:start(),
case apns:connect(cert, ?APNS_CONNECTION) of
{ok, PID} -> ?INFO_MSG("apns connection successful with PID ~p~n", [PID]);
{error, timeout} -> ?ERROR_MSG("apns connection unsuccessful reason timed out", [])
end,
apns_loop().
apns_loop() ->
receive
{reconnecting, ServerPid} -> %%do something;
{connection_up, ServerPid} -> %% do something;
Other -> %% do something
end,
apns_loop().
{正在重新连接,ServerPid}
到客户端进程,这意味着
apns4erl失去连接,正在尝试重新连接。一旦
连接已恢复,将显示一条{connection\u up,ServerPid}
消息
被派去
我的问题是:
- 要接收
或{reconnecting,ServerPid}
,我应该在{connection\u up,ServerPid}
中写入什么代码my_apns_module.erl
GenServerPid!{ok,10}
},由以下人员处理:
handle_info(Msg, State)
所以,你可以这样做:
start_link(Host, Opts) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
?GEN_SERVER:start_link({local, Proc}, ?MODULE,
[Host, Opts], []).
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).
stop(Host) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
?GEN_SERVER:call(Proc, stop),
supervisor:delete_child(ejabberd_sup, Proc),
ok.
init([Host, _Opts]) ->
...
handle_call(stop, _From, State) ->
{stop, normal, ok, State}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(#offline_msg{us = _UserServer,
from = From, to = To, packet = Packet} = _Msg, State) ->
...
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, State) ->
Host = State#state.host,
ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
handle_info({reconnecting, ServerPid}=Msg, State) ->
%%do something here, like log Msg or change State;
handl_info({connection_up, ServerPid}=Msg, State) ->
%%do something here, like log Msg or change State;
handle_info(#offline_msg{us = _UserServer,
from = From, to = To, packet = Packet} = _Msg, State) ->
%%do something.
init([Host, _Opts]) ->
spawn(?MODULE, start_apns, []),
...
start_apns() ->
apns:start(),
case apns:connect(cert, ?APNS_CONNECTION) of
{ok, PID} -> ?INFO_MSG("apns connection successful with PID ~p~n", [PID]);
{error, timeout} -> ?ERROR_MSG("apns connection unsuccessful reason timed out", [])
end,
apns_loop().
apns_loop() ->
receive
{reconnecting, ServerPid} -> %%do something;
{connection_up, ServerPid} -> %% do something;
Other -> %% do something
end,
apns_loop().
评论回复:
这是您当前的代码:
init([Host, _Opts]) ->
apns:start(),
case apns:connect(cert, ?APNS_CONNECTION) of
{ok, PID} -> ?INFO_MSG("apns connection successful with PID ~p~n", [PID]);
{error, timeout} -> ?ERROR_MSG("apns connection unsuccessful reason timed out", [])
end,
{ok, #state{host = Host}}.
您可以将其更改为以下内容:
start_link(Host, Opts) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
?GEN_SERVER:start_link({local, Proc}, ?MODULE,
[Host, Opts], []).
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).
stop(Host) ->
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
?GEN_SERVER:call(Proc, stop),
supervisor:delete_child(ejabberd_sup, Proc),
ok.
init([Host, _Opts]) ->
...
handle_call(stop, _From, State) ->
{stop, normal, ok, State}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(#offline_msg{us = _UserServer,
from = From, to = To, packet = Packet} = _Msg, State) ->
...
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, State) ->
Host = State#state.host,
ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
handle_info({reconnecting, ServerPid}=Msg, State) ->
%%do something here, like log Msg or change State;
handl_info({connection_up, ServerPid}=Msg, State) ->
%%do something here, like log Msg or change State;
handle_info(#offline_msg{us = _UserServer,
from = From, to = To, packet = Packet} = _Msg, State) ->
%%do something.
init([Host, _Opts]) ->
spawn(?MODULE, start_apns, []),
...
start_apns() ->
apns:start(),
case apns:connect(cert, ?APNS_CONNECTION) of
{ok, PID} -> ?INFO_MSG("apns connection successful with PID ~p~n", [PID]);
{error, timeout} -> ?ERROR_MSG("apns connection unsuccessful reason timed out", [])
end,
apns_loop().
apns_loop() ->
receive
{reconnecting, ServerPid} -> %%do something;
{connection_up, ServerPid} -> %% do something;
Other -> %% do something
end,
apns_loop().
启动apns进程后,apns进程将进入一个循环并等待消息。请稍候……消息不会发送到gen_服务器,比如GenServerPID,而是发送到gen_服务器内部运行的进程,比如PID。该进程是由语句{OK,PID}=apns:connect(cert,?apns\U CONNECTION)启动的。因此GenServerPID由ejabberd启动,PID通过我的apns模块内部的apns:connect启动。据我所知,handle_info将处理ejabberd服务器发送到GenServerPID的消息。它还会处理发送给PID的消息吗?据我所知,handle_info将处理ejabberd服务器发送给GenServerPID的消息。它还会处理发送到PID的消息吗?--发送到非gen_服务器进程的消息需要由receive子句处理。@GJain,我添加了一个您可以做的示例。很抱歉。。。我还有一个问题..spawn将启动一个新进程,比如说spawnPID..但是apns将消息发送给PID,所以(apns_循环处理spawnPID还是PID)或者(spawnPID==PID)?GJain,哪个进程是PID?在这种情况下,apns4erl将向客户端进程发送一条消息{reconnecting,ServerPid}——您必须找出哪个进程是
客户端进程。