1
我爲一個簡單的服務器程序編寫了這個模塊,該程序接收請求並向客戶端發送響應。它工作正常但是,如果在客戶端連接時重新編譯此模塊,則客戶端斷開連接,如果我將客戶端重新連接到此服務器併發送請求,則沒有響應。有什麼想法?!爲什麼代碼版本控制器在erlang中不起作用?
這裏是我的模塊:
-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.
我收到請求或響應後再次致電hander! – Amin
但是,當客戶端斷開時不行。正如你所說,「如果在客戶端連接時重新編譯這個模塊,**客戶端斷開連接**,並且如果我重新連接客戶端到這個服務器併發送請求,則沒有響應。你需要聽一個新的客戶。 –
我試過了但不起作用。 – Amin