erlang 如何接收发送到在gen_server内运行的PID的消息

2wnc66cl  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(152)
  • 我有一个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, 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}.
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}}.

如果网络中断或发生意外情况,则与苹果推送通知的枪连接将中断。在这种情况下,apns4erl将向客户端进程发送消息{reconnecting, ServerPid},这意味着apns4erl失去了连接,它正在尝试重新连接。一旦连接恢复,将发送消息{connection_up, ServerPid}
我的问题是:

  • 我应该在my_apns_module.erl内部编写什么代码来接收{reconnecting, ServerPid}{connection_up, ServerPid}
ulmd4ohb

ulmd4ohb1#

发送到gen_server进程(例如GenServerPid ! {ok, 10}})的消息由以下项处理:

handle_info(Msg, 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]) ->
      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}}.

您可以将其更改为如下形式:

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进程将进入循环并等待消息。

相关问题