Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang Tcp接受器模式_Tcp_Erlang - Fatal编程技术网

Erlang Tcp接受器模式

Erlang Tcp接受器模式,tcp,erlang,Tcp,Erlang,考虑以下因素(基于LYSE的sockserv) %%%负责所有套接字接收器的主管。 -模块(tcpsocket\u sup)。 -行为(主管)。 -导出([启动链接/0,启动套接字/0])。 -导出([init/1])。 启动链接()-> 主管:启动链接({local,?MODULE},?MODULE,[])。 init([])-> {ok,Port}=application:get_env(my_app,tcpPort), {ok,ListenSocket}=gen_-tcp:listen(

考虑以下因素(基于LYSE的sockserv)

%%%负责所有套接字接收器的主管。
-模块(tcpsocket\u sup)。
-行为(主管)。
-导出([启动链接/0,启动套接字/0])。
-导出([init/1])。
启动链接()->
主管:启动链接({local,?MODULE},?MODULE,[])。
init([])->
{ok,Port}=application:get_env(my_app,tcpPort),
{ok,ListenSocket}=gen_-tcp:listen(
港口,
[二进制,{packet,0},{reuseaddr,true},{active,true}],
lager:info(io_lib:format(“在端口~p上侦听TCP”,[port]),
生成链接(有趣的空侦听器/0),
{好的,{简单的{u一{u一},60,3600},
[{套接字,
{tcpserver,启动链接,[ListenSocket]},
临时的,1000,工作者,[tcpserver]}
]}}.
启动\u套接字()->
主管:启动子模块(?模块,[])。%,
空侦听器()->
[start_socket()| | |u
gen_服务器:启动链接(?模块,套接字,[])。
初始化(套接字)->
gen_服务器:强制转换(self(),accept),
{好的,#状态{socket=socket}。
处理呼叫(\u E,\u From,State)->
{诺雷普利州}。
handle_cast(accept,S=#state{socket=ListenSocket})->
{ok,AcceptSocket}=gen_tcp:accept(ListenSocket),
kvstore\u tcpsocket\u sup:start\u socket(),
接收
{tcp,套接字,}->
Uid=kvstore:store(值),
发送(套接字,Uid);
{tcp,套接字,}->
案例kvstore:检索
[{uu,Value}{124;]->
发送(套接字、值);
_ ->
发送(套接字,)
结束;
{tcp,套接字,{}->
发送(套接字,“无效消息”)
完,,
{noreply,S#state{socket=AcceptSocket,next=name}。
处理\u信息(\u,S)->
{诺雷普利,S}。
代码更改(_OldVsn,State,_Extra)->
{好的,州政府}。
终止(正常状态)->
好啊
终止(_原因,_状态)->
lager:info(“终止原因:~p~n”,[\u原因])。
发送(套接字、Bin)->
ok=gen_tcp:send(套接字,Bin),
ok=发电机tcp:关闭(插座),
好啊

我不清楚每个tcpserver进程是如何终止的?这是在泄漏进程吗?

我看不到任何地方您正在终止自己的进程

我想你要找的是四个案例:

  • 客户端终止连接(您收到
    tcp\u closed
  • 连接出现问题(您收到
    tcp\u错误
  • 服务器接收到要终止的系统消息(当然,这可能只是主管终止它,或者是终止消息)
  • 客户端发送一条消息,告诉服务器它已经完成了,您希望进行一些清理,而不仅仅是对
    tcp\u关闭做出反应
最常见的情况通常是客户端只是关闭连接,为此,您需要类似以下内容:

handle_info({tcp_closed, _}, State) ->
    {stop, normal, State};
连接变得奇怪总是有可能的。我想不出任何时候我都想拥有这个进程或套接字,所以:

%% You might want to log something here.
handle_info({tcp_error, _}, State) ->
    {stop, normal, State};
在任何情况下,客户机告诉服务器它已经完成了,并且您需要根据客户机已经成功地完成了一些事情来进行清理(可能您打开了应该首先写入的资源,或者打开了一个挂起的DB事务,或者其他什么)您希望从客户端收到一条成功消息,该消息以
send/2
的方式关闭连接,并返回
{stop,normal,State}
以停止进程

这里的关键是确保您确定要终止连接的情况,或者让服务器进程终止,或者(更好)返回
{stop,Reason,State}

如上所述,如果您希望
send/2
成为一个单独的响应和一个干净的退出(或者实际上,每个
accept
转换都应该导致一个
send/2
然后终止),那么您需要:

handle_cast(accept, S = #state{socket=ListenSocket}) ->
  {ok, AcceptSocket} = gen_tcp:accept(ListenSocket),
  kvstore_tcpsocket_sup:start_socket(),
  receive
    %% stuff that results in a call to send/2 in any case.
  end,
  {stop, normal, S}.
LYSE演示的情况是,连接是持久的,客户端和服务器之间来回进行。在上述情况下,您正在处理单个请求,生成一个新的侦听器以重新填充侦听器池,并且应该退出,因为您不打算让此gen_服务器做任何进一步的工作

%% You might want to log something here.
handle_info({tcp_error, _}, State) ->
    {stop, normal, State};
handle_cast(accept, S = #state{socket=ListenSocket}) ->
  {ok, AcceptSocket} = gen_tcp:accept(ListenSocket),
  kvstore_tcpsocket_sup:start_socket(),
  receive
    %% stuff that results in a call to send/2 in any case.
  end,
  {stop, normal, S}.