Kaynağa Gözat

Implement better websocket exit mechanism

GilbertWong 6 yıl önce
ebeveyn
işleme
953d320667
2 değiştirilmiş dosya ile 19 ekleme ve 9 silme
  1. 7 0
      src/emqx_session.erl
  2. 12 9
      src/emqx_ws_channel.erl

+ 7 - 0
src/emqx_session.erl

@@ -331,6 +331,10 @@ update_expiry_interval(SPid, Interval) ->
 close(SPid) ->
     gen_server:call(SPid, close).
 
+-spec(close(spid(), atom()) -> ok).
+close(SPid, Reason) ->
+    gen_server:call(SPid, {close, Reason}).
+
 %%------------------------------------------------------------------------------
 %% gen_server callbacks
 %%------------------------------------------------------------------------------
@@ -457,6 +461,9 @@ handle_call({pubrel, PacketId, _ReasonCode}, _From, State = #state{awaiting_rel
 handle_call(close, _From, State) ->
     {stop, normal, ok, State};
 
+handle_call({close, Reason}, _From, State) ->
+    {stop, Reason, ok, State};
+
 handle_call(Req, _From, State) ->
     ?LOG(error, "Unexpected call: ~p", [Req]),
     {reply, ignored, State}.

+ 12 - 9
src/emqx_ws_channel.erl

@@ -303,20 +303,23 @@ websocket_info(Info, State) ->
     ?LOG(error, "Unexpected info: ~p", [Info]),
     {ok, State}.
 
-terminate(SockError, _Req, #state{keepalive   = Keepalive,
-                                  proto_state = ProtoState,
-                                  shutdown    = Shutdown}) ->
-    ?LOG(debug, "Terminated for ~p, sockerror: ~p",
-         [Shutdown, SockError]),
+terminate(WsReason, _Req, #state{keepalive   = Keepalive,
+                                 proto_state = ProtoState,
+                                 shutdown    = Shutdown}) ->
+    ?LOG(debug, "Terminated for ~p, websocket reason: ~p",
+         [Shutdown, WsReason]),
     emqx_keepalive:cancel(Keepalive),
     case {ProtoState, Shutdown} of
         {undefined, _} -> ok;
         {_, {shutdown, Reason}} ->
+            SessionPid = emqx_protocol:session(ProtoState),
             emqx_protocol:terminate(Reason, ProtoState),
-            exit(Reason);
-        {_, Error} ->
-            emqx_protocol:terminate(Error, ProtoState),
-            exit({error, SockError})
+            SessionPid ! {'EXIT', self(), Reason};
+        {_, _Error} ->
+            ?LOG(info, "Terminate for unexpected error: ~p", [WsReason]),
+            SessionPid = emqx_protocol:session(ProtoState),
+            emqx_protocol:terminate(unknown, ProtoState),
+            SessionPid ! {'EXIT', self(), unknown}
     end.
 
 %%--------------------------------------------------------------------