diff --git a/src/host/iot_host.erl b/src/host/iot_host.erl index 3c89ced..8f56320 100644 --- a/src/host/iot_host.erl +++ b/src/host/iot_host.erl @@ -311,13 +311,17 @@ handle_event(cast, heartbeat, _, State = #state{uuid = UUID, heartbeat_counter = maybe_mark_host_online(UUID), {keep_state, State#state{heartbeat_counter = HeartbeatCounter + 1}}; -%% 没有收到心跳包,主机下线, 设备状态不变 -handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{uuid = UUID, heartbeat_counter = 0, channel_pid = ChannelPid}) -> +%% UDP 心跳丢失但 SSL channel 仍在时,不能把 host 标记为离线。 +handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{uuid = UUID, heartbeat_counter = 0, channel_pid = ChannelPid}) when is_pid(ChannelPid) -> + logger:warning("[iot_host] uuid: ~p, udp heartbeat lost but ssl channel is alive: ~p", [UUID, ChannelPid]), + maybe_mark_host_online(UUID), + erlang:start_timer(?HEARTBEAT_INTERVAL, self(), heartbeat_ticker), + {keep_state, State#state{heartbeat_counter = 0}}; + +%% 没有收到 UDP 心跳且没有 SSL channel,主机下线, 设备状态不变 +handle_event(info, {timeout, _, heartbeat_ticker}, _, State = #state{uuid = UUID, heartbeat_counter = 0}) -> logger:warning("[iot_host] uuid: ~p, heartbeat lost, devices will unknown", [UUID]), maybe_mark_host_offline(UUID), - - %% 关闭channel,主机需要重新连接,才能保存状态的一致 - is_pid(ChannelPid) andalso ssl_channel:stop(ChannelPid, closed), erlang:start_timer(?HEARTBEAT_INTERVAL, self(), heartbeat_ticker), {keep_state, State#state{channel_pid = undefined, has_session = false, heartbeat_counter = 0}};