如果 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}.