diff options
author | Jeremy Ong <[email protected]> | 2012-12-19 11:34:44 -0800 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2012-12-22 18:32:15 +0100 |
commit | 5f122d9fa670f9c239f3f68b4053b35884704f9e (patch) | |
tree | 2e08bf0a6117767e02eaa465382864e4dede69b7 /src | |
parent | a07d063fd8fc8a1cfadcb35cc89e190695773fe8 (diff) | |
download | cowboy-5f122d9fa670f9c239f3f68b4053b35884704f9e.tar.gz cowboy-5f122d9fa670f9c239f3f68b4053b35884704f9e.tar.bz2 cowboy-5f122d9fa670f9c239f3f68b4053b35884704f9e.zip |
Cancel timer only on websocket_data receives or sends
This commit prevents erlang messages from keeping a websocket connection
alive. Previously, the timer was canceled upon any activity. Now, the
timeout is only canceled when actual data is sent from the client. The
handler_loop_timeout/1 function is called from websocket_data/4 instead
of handler_before_loop/4. It is also called after every successful reply
in handler_call/4.
Diffstat (limited to 'src')
-rw-r--r-- | src/cowboy_websocket.erl | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/src/cowboy_websocket.erl b/src/cowboy_websocket.erl index 8b01522..8c02ac7 100644 --- a/src/cowboy_websocket.erl +++ b/src/cowboy_websocket.erl @@ -188,7 +188,8 @@ websocket_handshake(State=#state{transport=Transport, challenge=Challenge}, Req), %% Flush the resp_sent message before moving on. receive {cowboy_req, resp_sent} -> ok after 0 -> ok end, - handler_before_loop(State#state{messages=Transport:messages()}, + State2 = handler_loop_timeout(State), + handler_before_loop(State2#state{messages=Transport:messages()}, Req2, HandlerState, <<>>). -spec handler_before_loop(#state{}, cowboy_req:req(), any(), binary()) -> closed. @@ -196,15 +197,13 @@ handler_before_loop(State=#state{ socket=Socket, transport=Transport, hibernate=true}, Req, HandlerState, SoFar) -> Transport:setopts(Socket, [{active, once}]), - State2 = handler_loop_timeout(State), catch erlang:hibernate(?MODULE, handler_loop, - [State2#state{hibernate=false}, Req, HandlerState, SoFar]), + [State#state{hibernate=false}, Req, HandlerState, SoFar]), closed; handler_before_loop(State=#state{socket=Socket, transport=Transport}, Req, HandlerState, SoFar) -> Transport:setopts(Socket, [{active, once}]), - State2 = handler_loop_timeout(State), - handler_loop(State2, Req, HandlerState, SoFar). + handler_loop(State, Req, HandlerState, SoFar). -spec handler_loop_timeout(#state{}) -> #state{}. handler_loop_timeout(State=#state{timeout=infinity}) -> @@ -222,7 +221,8 @@ handler_loop(State=#state{ Req, HandlerState, SoFar) -> receive {OK, Socket, Data} -> - websocket_data(State, Req, HandlerState, + State2 = handler_loop_timeout(State), + websocket_data(State2, Req, HandlerState, << SoFar/binary, Data/binary >>); {Closed, Socket} -> handler_terminate(State, Req, HandlerState, {error, closed}); @@ -460,7 +460,8 @@ handler_call(State=#state{handler=Handler, opts=Opts}, Req, HandlerState, when is_tuple(Payload) -> case websocket_send(Payload, State) of ok -> - NextState(State, Req2, HandlerState2, RemainingData); + State2 = handler_loop_timeout(State), + NextState(State2, Req2, HandlerState2, RemainingData); shutdown -> handler_terminate(State, Req2, HandlerState, {normal, shutdown}); @@ -471,7 +472,8 @@ handler_call(State=#state{handler=Handler, opts=Opts}, Req, HandlerState, when is_tuple(Payload) -> case websocket_send(Payload, State) of ok -> - NextState(State#state{hibernate=true}, + State2 = handler_loop_timeout(State), + NextState(State2#state{hibernate=true}, Req2, HandlerState2, RemainingData); shutdown -> handler_terminate(State, Req2, HandlerState, @@ -483,7 +485,8 @@ handler_call(State=#state{handler=Handler, opts=Opts}, Req, HandlerState, when is_list(Payload) -> case websocket_send_many(Payload, State) of ok -> - NextState(State, Req2, HandlerState2, RemainingData); + State2 = handler_loop_timeout(State), + NextState(State2, Req2, HandlerState2, RemainingData); shutdown -> handler_terminate(State, Req2, HandlerState, {normal, shutdown}); @@ -494,7 +497,8 @@ handler_call(State=#state{handler=Handler, opts=Opts}, Req, HandlerState, when is_list(Payload) -> case websocket_send_many(Payload, State) of ok -> - NextState(State#state{hibernate=true}, + State2 = handler_loop_timeout(State), + NextState(State2#state{hibernate=true}, Req2, HandlerState2, RemainingData); shutdown -> handler_terminate(State, Req2, HandlerState, |