使用websocket向所有连接的用户广播消息(Erlang,RabbitMQ,Websocket,Gen_bunny,Cowboy)

时间:2013-05-01 08:46:03

标签: erlang websocket rabbitmq cowboy

我正在尝试使用ERlang,Cowboy,Websocket和gen_bunny整合websocket聊天。

我能够让他们独立工作。

浏览器 - >牛仔websocket聊天(作品) Erlang和RabbitMQ AMQP(作品)

当将它们集成在一起时,我能够从浏览器获取消息并将其传递给RabbitMQ并再次从RabbitMQ返回。

我甚至可以将消息回复给发送它的用户。但是,我想将消息广播给所有连接的用户。

根据我的理解,Erlang将为每个用户创建一个单独的进程。那么,在我从RabbitMQ获取响应后,如何将它广播给所有连接的用户?

3 个答案:

答案 0 :(得分:1)

正确 - Cowboy创建一个运行WebSocket处理程序代码的每个连接进程。一种方法是让处理程序的websocket_init/3函数自身注册一个“广播”进程(并在websocket_terminate/3中取消注册)。收到来自RabbitMQ的消息后,广播进程会将消息重复到所有已注册的WebSocket连接,这些连接可以使用websocket_info/3处理程序回调来接收它。

广播进程可以使用monitors来发现WebSocket处理程序何时死亡,并自动将其从注册列表中删除。

然后,处理程序的生命可能如下所示:

    在Cowboy执行websocket_init/3(WebSocket)中请求的协议升级后,调用
  1. init/3。从这里开始,客户端处理程序将自己注册到消息广播过程broadcast
  2. 只要连接保持打开状态,处理程序就会向其websocket_info/3接收消息广播,并通过返回{reply, {text, Message}, State}将消息传递给客户端。
  3. 终止后,处理程序会使用broadcast取消注册。如果由于某种原因这不能按预期工作,broadcast会保留所有订阅者的监视器,以便收到他们死亡的通知。

答案 1 :(得分:1)

看看gproc项目:https://github.com/uwiger/gproc

它有一个Pub / Sub模式,您可以用它来构建您提到的聊天。

来自gproc的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}). 

答案 2 :(得分:0)

每个牛仔进程都有自己的Rabbit队列。广播将与通配符绑定一起使用。没有明确的循环。您可以通过不相应的绑定使订阅成为可选。请参阅:How to setup queue such a way all subscribers get messages - Rabbit MQ