简体   繁体   中英

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

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??

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.

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}). 

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM