当前位置:  开发笔记 > 编程语言 > 正文

当handle_call返回noreply时,erlang otp gen_server会丢弃连接

如何解决《当handle_call返回noreply时,erlangotpgen_server会丢弃连接》经验,为你挑选了1个好方法。

启动服务器使用:

erlc server.erl ; erl -eval 'server:start()'

在另一个终端:

telnet localhost 3547

哪个可以成功建立连接,但在几秒钟内,由于我之外的原因,服务器关闭了连接.阅读该文档handle_call/3,{noreply, NewState}被允许为好.

有人可以解释一下吗?感觉超级混乱我.

源代码

-module(server).
-mode(compile).
-behavior(gen_server).

-compile(export_all).

-export([   main/1
          , start/0
          , stop/0
          , stop_and_wait/0
        ]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
        terminate/2, code_change/3]).

-define(SERVER, ?MODULE).
-define(DEFAULT_PORT, 3547).

-record(state, {port, lsock}).

start_link(Port) ->
  gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []).

start() ->
  start_link(?DEFAULT_PORT).

stop() ->
  gen_server:cast(?SERVER, stop).

stop_and_wait() ->
  gen_server:call(?SERVER, stop, infinity).

init([Port]) ->
  {ok, LSock} = gen_tcp:listen(Port, [{active, false}, {reuseaddr, true}]),
  {ok, #state{port = Port, lsock = LSock}, 0}.

handle_call({do_stuff, Arg}, _From, State) ->
  io:format("do_stuff is called with ~p~n", [Arg]),
  % {reply, ok, State};
  {noreply, State};

handle_call(stop, _From, State) ->
  {stop, normal, ok, State}.

handle_cast(stop, State) ->
  {stop, normal, State}.

handle_info(timeout, #state{lsock = LSock} = State) ->
  Server = self(),
  Listener = spawn(fun() -> listen(Server, LSock) end),
  {noreply, State}.

terminate(_Reason, _State) ->
  ok.

code_change(_Oldvsn, State, _Extra) ->
  {ok, State}.

listen(Server, LSock) ->
  {ok, Socket} = gen_tcp:accept(LSock),
  gen_server:call(?SERVER, {do_stuff, 1}),
  listen(Server, LSock).

main(_) ->
  io:format("~p~n", [ok]),
  ok.

Steve Vinosk.. 9

允许{noreply, NewState}gen_server:handle_call/3实现返回,但这并不意味着gen_server不必回复该调用.相反,在这种情况下,假设gen_server将在稍后使用该gen_server:reply/2呼叫回复.

默认超时为gen_server:call/2,35秒.您的代码中发生的事情是您的listen/2函数在接受套接字的进程中运行,因此是该套接字的所有者,然后调用它gen_server:call(?SERVER, {do_stuff, 1}).由于您gen_server没有回复该呼叫,因此gen_server:call5秒后超时,终止进程并因此关闭套接字.



1> Steve Vinosk..:

允许{noreply, NewState}gen_server:handle_call/3实现返回,但这并不意味着gen_server不必回复该调用.相反,在这种情况下,假设gen_server将在稍后使用该gen_server:reply/2呼叫回复.

默认超时为gen_server:call/2,35秒.您的代码中发生的事情是您的listen/2函数在接受套接字的进程中运行,因此是该套接字的所有者,然后调用它gen_server:call(?SERVER, {do_stuff, 1}).由于您gen_server没有回复该呼叫,因此gen_server:call5秒后超时,终止进程并因此关闭套接字.

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有