如果TCP連接本身已超時,那麼您應該收到一封閉的套接字消息{tcp_closed, Socket}
。與handle_info
匹配就是這樣。至於在連接上建立你自己的超時,我通常用erlang:send_after/3
給自己發送一條消息 - 有效地添加一個超時消息語義,我可以在handle_info
或任何可能存在的receive
服務循環中收到。
erlang:send_after(?IDLE_TIMEOUT, self(), {tcp_timeout, Socket})
這必須是每次接收到交通定時器的取消配對。這可能看起來像這樣:
handle_info({tcp, Socket, Bin}, State = #s{timer = T, socket = Socket}) ->
_ = erlang:cancel_timer(T),
{Messages, NewState} = interpret(Bin, State),
ok = handle(Messages),
NewT = erlang:send_after(?IDLE_TIMEOUT, self(), {tcp_timeout, Socket})
{noreply, NewState#s{timer = NewT}};
handle_info({tcp_closed, Socket}, State = #s{timer = T, socket = Socket}) ->
_ = erlang:cancel_timer(T),
NewState = handle_close(State),
{noreply, NewState};
handle_info({tcp_timeout, Socket}, State = #s{socket = Socket}) ->
NewState = handle_timeout(State),
{noreply, NewState};
handle_info(Unexpected, State) ->
ok = log(warning, "Received unexpected message: ~tp", [Unexpected]),
{noreply, State}.
不知道爲什麼有人低估了這一點。這是許多人很早就用Erlang,Elixir,LFE等人使用'{active,true}'套接字所面臨的一個基本難題 - 而且這個解決方案不僅適用於Elixir。 – zxq9