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:
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. websocket_info/3
, passing messages along to the client by returning {reply, {text, Message}, State}
. 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.