为啥代码版本控制器在 erlang 中不起作用?
Posted
技术标签:
【中文标题】为啥代码版本控制器在 erlang 中不起作用?【英文标题】:Why code version controller does not work in erlang?为什么代码版本控制器在 erlang 中不起作用? 【发布时间】:2015-12-17 09:49:45 【问题描述】:我为一个简单的服务器程序编写了这个模块,该程序接收请求并向客户端发送响应。它工作正常但是如果在客户端连接时重新编译此模块,客户端将断开连接,并且如果我将客户端重新连接到此服务器并发送请求,则没有响应。有什么想法吗?!
这是我的模块:
-module(controller).
-export([start/1, loop/1, response/2]).
-include_lib("types.hrl").
-define(END_CHAR, "$").
-spec start(Port) -> no_return() when
Port :: char().
-spec loop(Listen) -> no_return() when
Listen :: port().
-spec handler(Socket) -> no_return() when
Socket :: port().
-spec response(HandlerPID, Data) -> send_msg, Msg when
HandlerPID :: pid(),
Data :: string(),
Msg :: response().
start(Port) ->
ok, Listen = gen_tcp:listen(Port, [active, once]),
spawn(?MODULE, loop, [Listen]).
loop(Listen) ->
ok, Socket = gen_tcp:accept(Listen),
spawn(?MODULE, loop, [Listen]),
handler(Socket).
handler(Socket) ->
receive
tcp, Socket, Data ->
%io:format("recv ~p~n", [Data]),
spawn(?MODULE, response, [self(), Data]),
inet:setopts(Socket, [active, once]),
handler(Socket);
tcp_closed, Socket ->
%io:format("disconnected~n", []),
gen_tcp:close(Socket);
send_msg, Msg ->
gen_tcp:send(Socket, lists:flatten(io_lib:format("~p", [Msg])) ++ ?END_CHAR),
handler(Socket)
end.
response(PID, Data) ->
[Req|Args] = string:tokens(Data, ?END_CHAR),
ReqPID, ReqRef = spawn_monitor(view, request, [list_to_atom(Req), self(), Args]),
receive
'DOWN', ReqRef, process, ReqPID, function_clause, _ -> PID ! send_msg, invalid_request;
'DOWN', ReqRef, process, ReqPID, case_clause, _, _ -> PID ! send_msg, bad_args;
'DOWN', ReqRef, process, ReqPID, badmatch, _, _ -> PID ! send_msg, bad_args;
Resp -> PID ! send_msg, Resp
end.
【问题讨论】:
【参考方案1】:注意
tcp_closed, Socket ->
%io:format("disconnected~n", []),
gen_tcp:close(Socket);
在handler
。它不再调用handler
,它只是返回,因此服务器进程停止。
您的 loop
函数名称也具有误导性,handler
是实际循环。
【讨论】:
hander收到请求或响应后我再次调用它! 但不是在客户端断开连接时。正如您所说,“如果在客户端连接时重新编译此模块,客户端断开并且如果我将客户端重新连接到该服务器并发送请求,则没有响应”。您需要倾听新客户。 另外,这可能是开始学习 OTP 的好时机:将您的服务器转换为gen_server
并将其放在 supervisor
下,它将自动重新启动。
然后在问题中包含更新的代码,它可能由于其他原因不起作用。【参考方案2】:
我建议看一下Ranch - TCP 连接的套接字接受器池。
【讨论】:
以上是关于为啥代码版本控制器在 erlang 中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 setText() 在 TextView 上的以下代码中不起作用?