为啥代码版本控制器在 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 中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为什么这个递归打印功能在Erlang中不起作用

为啥媒体查询在 Angular8 中不起作用

为啥代码覆盖率在 ReSharper 中不起作用?

为啥 setText() 在 TextView 上的以下代码中不起作用?

为啥这个简单的 SQL 代码在 Azure Databricks 中不起作用?

为啥我的媒体查询代码在 CSS 中不起作用?