Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add a broadcast API. #231

Merged
merged 1 commit into from

4 participants

@davidw
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

@davidw 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
@davidw
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.

@kotedo
@evanmiller
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.

@evanmiller evanmiller merged commit d41471a into ChicagoBoss:master
@adrianrosian

Hello, guys,

Examples for using this?

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

@davidw
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. @davidw

    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
View
11 doc-src/api-websocket.html
@@ -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>
View
25 src/boss/boss_service_worker.erl
@@ -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.