From 09914c4693562bfde644b73a2ed5e6bac7362b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Thu, 11 Oct 2012 21:46:43 +0200 Subject: Allow websocket handlers to reply more than one frame Instead of returning {text, Data}, you can now return [{text, Data}, {text, Data2}, ...]. --- src/cowboy_websocket.erl | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/cowboy_websocket.erl b/src/cowboy_websocket.erl index bc88011..1c6d20c 100644 --- a/src/cowboy_websocket.erl +++ b/src/cowboy_websocket.erl @@ -450,11 +450,22 @@ handler_call(State=#state{handler=Handler, opts=Opts}, Req, HandlerState, {ok, Req2, HandlerState2, hibernate} -> NextState(State#state{hibernate=true}, Req2, HandlerState2, RemainingData); - {reply, Payload, Req2, HandlerState2} -> - websocket_send(Payload, State), + {reply, Payload, Req2, HandlerState2} + when is_tuple(Payload) -> + ok = websocket_send(Payload, State), NextState(State, Req2, HandlerState2, RemainingData); - {reply, Payload, Req2, HandlerState2, hibernate} -> - websocket_send(Payload, State), + {reply, Payload, Req2, HandlerState2, hibernate} + when is_tuple(Payload) -> + ok = websocket_send(Payload, State), + NextState(State#state{hibernate=true}, + Req2, HandlerState2, RemainingData); + {reply, Payload, Req2, HandlerState2} + when is_list(Payload) -> + ok = websocket_send_many(Payload, State), + NextState(State, Req2, HandlerState2, RemainingData); + {reply, Payload, Req2, HandlerState2, hibernate} + when is_list(Payload) -> + ok = websocket_send_many(Payload, State), NextState(State#state{hibernate=true}, Req2, HandlerState2, RemainingData); {shutdown, Req2, HandlerState2} -> @@ -471,14 +482,15 @@ handler_call(State=#state{handler=Handler, opts=Opts}, Req, HandlerState, websocket_close(State, Req, HandlerState, {error, handler}) end. --spec websocket_send(binary(), #state{}) -> closed | ignore. +-spec websocket_send({text | binary | ping | pong, binary()}, #state{}) + -> ok | {error, atom()}. %% hixie-76 text frame. websocket_send({text, Payload}, #state{ socket=Socket, transport=Transport, version=0}) -> Transport:send(Socket, [0, Payload, 255]); %% Ignore all unknown frame types for compatibility with hixie 76. websocket_send(_Any, #state{version=0}) -> - ignore; + ok; websocket_send({Type, Payload}, #state{socket=Socket, transport=Transport}) -> Opcode = case Type of text -> 1; @@ -490,6 +502,14 @@ websocket_send({Type, Payload}, #state{socket=Socket, transport=Transport}) -> Transport:send(Socket, [<< 1:1, 0:3, Opcode:4, 0:1, Len/bits >>, Payload]). +-spec websocket_send_many([{text | binary | ping | pong, binary()}], #state{}) + -> ok | {error, atom()}. +websocket_send_many([], _) -> + ok; +websocket_send_many([Frame|Tail], State) -> + ok = websocket_send(Frame, State), + websocket_send_many(Tail, State). + -spec websocket_close(#state{}, cowboy_req:req(), any(), {atom(), atom()}) -> closed. websocket_close(State=#state{socket=Socket, transport=Transport, version=0}, -- cgit v1.2.3