Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add a broadcast API. #231

Merged
merged 1 commit into from

4 participants

David N. Welton Kai Janson Evan Miller Adrian Rosian
David N. Welton
Owner

Alerts the web socket handler to the need to broadcast a message to some or all of the connected web sockets. It is up to the developer to keep track of the connected sockets.

See also: #193

David N. Welton davidw Add a broadcast API.
Alerts the web socket handler to the need to broadcast a message to
some or all of the connected web sockets.  It is up to the developer
to keep track of the connected sockets.
b0d0dc1
David N. Welton
Owner

The only thing I don't like about this approach is that for someone just getting started, figuring out all the web socket tracking code in their own handle_join / handle_close is going to be a pain.

Kai Janson
Evan Miller
Owner

This patch feels like the right approach so I am merging it in. As Kai suggested I think the solution to the learning curve is to have some example code or a skeleton handler of some sort. I suppose in the future we could move to a higher level API with "groups" or something, but for now this seems good enough to me.

Evan Miller evanmiller merged commit d41471a into from
Adrian Rosian

Hello, guys,

Examples for using this?

Edit: Issued a pull request with documentation for calling boss_service_worker:broadcast/2

David N. Welton
Owner

Sorry, I don't have any handy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 27, 2013
  1. David N. Welton

    Add a broadcast API.

    davidw authored
    Alerts the web socket handler to the need to broadcast a message to
    some or all of the connected web sockets.  It is up to the developer
    to keep track of the connected sockets.
This page is out of date. Refresh to see the latest.
Showing with 34 additions and 2 deletions.
  1. +11 −0 doc-src/api-websocket.html
  2. +23 −2 src/boss/boss_service_worker.erl
11 doc-src/api-websocket.html
View
@@ -43,6 +43,17 @@
<p>Handle an incoming message from a client.</p>
<div class="code spec">
+ handle_broadcast(Message::term(), State) -&gt;<br>
+ &nbsp;&nbsp;{noreply, NewState} |<br>
+ &nbsp;&nbsp;{noreply, NewState, Timeout} |<br>
+ &nbsp;&nbsp;{stop, Reason, NewState}
+</div>
+<p>Handle an outgoing broadcast message from some Erlang process to
+the connected web sockets. It is your responsibility to keep track of
+the web sockets (via handle_join and handle_close) and send the
+outgoing messages as you see fit.</p>
+
+<div class="code spec">
handle_info(Info, State) -&gt;<br>
&nbsp;&nbsp;{noreply, NewState} |<br>
&nbsp;&nbsp;{noreply, NewState, Timeout} |<br>
25 src/boss/boss_service_worker.erl
View
@@ -12,7 +12,7 @@
%% API
-export([start_link/2]).
--export([incoming/5, join/4, close/4]).
+-export([incoming/5, join/4, close/4, broadcast/2]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -42,6 +42,9 @@ incoming(Service, ServiceUrl, WebSocketId, SessionId, Msg) ->
join(Service, ServiceUrl, WebSocketId, SessionId) ->
gen_server:call({global, Service}, {join_service, ServiceUrl, WebSocketId, SessionId }).
+broadcast(Service, Message) ->
+ gen_server:cast({global, Service}, {broadcast, Message}).
+
close(Service, ServiceUrl, WebSocketId, SessionId) ->
gen_server:call({global, Service}, {terminate_service, ServiceUrl, WebSocketId, SessionId}).
@@ -121,7 +124,6 @@ handle_call({join_service, ServiceUrl, WebSocketId, SessionId}, _From, State) ->
SessionId, Internal, erlang:get_stacktrace()])
end;
-
handle_call({terminate_service, ServiceUrl, WebSocketId, SessionId}, _From, State) ->
#state{handler=Handler, internal=Internal} = State,
try Handler:handle_close(ServiceUrl, WebSocketId, SessionId, Internal) of
@@ -190,6 +192,25 @@ handle_cast({incoming_msg, ServiceUrl, WebSocketId, SessionId, Message}, State)
SessionId, Message, Internal, erlang:get_stacktrace()])
end;
+handle_cast({broadcast, Message}, State) ->
+ #state{handler=Handler, internal=Internal} = State,
+ try Handler:handle_broadcast(Message, Internal) of
+ {noreply, NewInternal} ->
+ {noreply, #state{handler=Handler, internal=NewInternal}};
+ {noreply, NewInternal, Timeout} ->
+ {noreply, #state{handler=Handler, internal=NewInternal}, Timeout};
+ {stop, _Reason, NewInternal} ->
+ {stop, _Reason, #state{handler=Handler, internal=NewInternal}}
+ catch Class:Reason ->
+ error_logger:error_msg(
+ "** Boss Service Handler ~p terminating in broadcast~n"
+ " for the reason ~p:~p~n"
+ "Message : ~p~n"
+ "State : ~p~n"
+ "** Stacktrace: ~p~n~n",
+ [Handler, Class, Reason, Message, Internal, erlang:get_stacktrace()])
+ end;
+
handle_cast(_Msg, State) ->
{noreply, State}.
Something went wrong with that request. Please try again.