Broadcasting message to all connected users using websocket (Erlang, RabbitMQ, Websocket, Gen_bunny, Cowboy)

StackOverflow https://stackoverflow.com/questions/16315204

Question

I am trying to integrate websocket chat using ERlang, Cowboy, Websocket and gen_bunny.

I am able to get them work independently.

Browser -> Cowboy websocket chat (Works) Erlang and RabbitMQ AMQP (Works)

When integrating them together i am able to get the message from browser to Cowboy and pass it to RabbitMQ and again get it back from RabbitMQ.

I can even reply the message to the user who sent it. However, I want to broadcast the message to all connected Users.

As per my understanding Erlang will create a separate process for each user. So, how to broadcast it to all connected users after I get back the response from RabbitMQ??

Was it helpful?

Solution 2

Take a look on gproc project: https://github.com/uwiger/gproc

It has a Pub/Sub pattern that you may use to build the chat you mentioned.

From gproc's wiki:

subscribe(EventType) ->
    %% Gproc notation: {p, l, Name} means {(p)roperty, (l)ocal, Name}
    gproc:reg({p, l, {?MODULE, EventType}}).

notify(EventType, Msg) -> 
    Key = {?MODULE, EventType},
    gproc:send({p, l, Key}, {self(), Key, Msg}). 

OTHER TIPS

Correct--Cowboy creates a per-connection process that runs your WebSocket handler code. One approach is to have the handler's websocket_init/3 function register itself with a "broadcast" process (and unregister in websocket_terminate/3). Upon receiving a message from RabbitMQ, the broadcast process repeats the message to all registered WebSocket connections, which can receive it using the websocket_info/3 handler callback.

The broadcast process can use monitors to discover when a WebSocket handler dies, and automatically remove it from the registration list.

The life of a handler, then, might look something like this:

  1. websocket_init/3 is called after Cowboy performs the protocol upgrade requested in init/3 (to WebSocket). From here, the client handler registers itself with broadcast, the message broadcasting process.
  2. As long as the connection remains open, the handler receives message broadcasts to its websocket_info/3, passing messages along to the client by returning {reply, {text, Message}, State}.
  3. Upon termination, the handler unregisters itself with broadcast. If for some reason this doesn't work as intended, broadcast keeps monitors on all subscribers so as to get notified of their deaths.

Every cowboy process get its own Rabbit queue. Broadcast would work with wildcard bindings. No explicit loop involved. You could make the subscription optional by not binding accordingly. See: How to setup queue such a way all subscribers get messages - Rabbit MQ

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top