我正在尝试使用ERlang,Cowboy,Websocket和gen_bunny整合websocket聊天。
我能够让他们独立工作。
浏览器 - >牛仔websocket聊天(作品) Erlang和RabbitMQ AMQP(作品)
当将它们集成在一起时,我能够从浏览器获取消息并将其传递给RabbitMQ并再次从RabbitMQ返回。
我甚至可以将消息回复给发送它的用户。但是,我想将消息广播给所有连接的用户。
根据我的理解,Erlang将为每个用户创建一个单独的进程。那么,在我从RabbitMQ获取响应后,如何将它广播给所有连接的用户?
答案 0 :(得分:1)
正确 - Cowboy创建一个运行WebSocket处理程序代码的每个连接进程。一种方法是让处理程序的websocket_init/3
函数自身注册一个“广播”进程(并在websocket_terminate/3
中取消注册)。收到来自RabbitMQ的消息后,广播进程会将消息重复到所有已注册的WebSocket连接,这些连接可以使用websocket_info/3
处理程序回调来接收它。
广播进程可以使用monitors来发现WebSocket处理程序何时死亡,并自动将其从注册列表中删除。
然后,处理程序的生命可能如下所示:
websocket_init/3
(WebSocket)中请求的协议升级后,调用init/3
。从这里开始,客户端处理程序将自己注册到消息广播过程broadcast
。websocket_info/3
接收消息广播,并通过返回{reply, {text, Message}, State}
将消息传递给客户端。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