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

使用websocket(Erlang、RabbitMQ、websocket、Gen_bunny、Cowboy)向所有连接的用户广播消息,erlang,websocket,rabbitmq,cowboy,Erlang,Websocket,Rabbitmq,Cowboy,我正在尝试使用ERlang、Cowboy、websocket和gen_bunny集成websocket聊天 我能够让他们独立工作 浏览器->牛仔websocket聊天(作品) Erlang和RabbitMQ AMQP(工程) 当将它们集成在一起时,我能够从浏览器中获取消息,并将其传递给RabbitMQ,然后再从RabbitMQ中获取 我甚至可以将消息回复给发送消息的用户。但是,我想向所有连接的用户广播该消息 据我所知,Erlang将为每个用户创建一个单独的进程。那么,在我从RabbitMQ获得响

我正在尝试使用ERlang、Cowboy、websocket和gen_bunny集成websocket聊天

我能够让他们独立工作

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

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

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

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

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

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

那么,处理程序的生命可能是这样的:

  • 在Cowboy执行
    init/3
    中请求的协议升级(到websocket)后,调用
    websocket\u init/3
    。从这里开始,客户机处理程序将自己注册到消息广播过程
    broadcast
  • 只要连接保持打开状态,处理程序就会接收消息广播到其
    websocket\u info/3
    ,通过返回
    {reply,{text,message},State}
    将消息传递给客户端
  • 终止后,处理程序将使用
    广播
    注销自身。如果由于某种原因,此功能无法按预期工作,
    广播
    会在所有订阅者身上保留监视器,以便获得死亡通知

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

    每个牛仔进程都有自己的兔子队列。广播将使用通配符绑定。不涉及显式循环。您可以通过不相应地绑定使订阅成为可选的。请参阅:

    嘿,Edyardo,谢谢您的回复。。然而,在使用RabbitMQ之前,我对Gproc进行了实验。问题是将有许多cowboy实例在运行,从可伸缩性的角度来看,我想使用消息队列。嗯。。我懂了。但是你看到gproc支持本地和全局进程了吗?我想我会稍微改变一下架构,并将gproc和RabbitMQ结合使用……谢谢Martin,但我想避免循环,因为用户数量和消息交换将很高。因此,在收到来自RabbitMQ的消息后,如果我运行一个循环并将消息发送给所有人,那么在将来它将成为瓶颈。有没有其他框架可以完成广播任务?我看过YAWS和Cowboy…Erlang中的消息传递速度非常快(通常是异步的)。除非你已经测量过,否则不要认为它会成为瓶颈。在某种程度上,除非您使用某种复杂的map-reduce-like模式来并行化广播,否则您将有一个循环,该循环将顺序地向订阅者发送消息。据我所知,这里并没有什么灵丹妙药。嗯……我曾经用Tsung进行基准测试,但结果并不是很有希望。尽管如此,我还是在考虑一起使用GProc和RabbitMQ。@MartinTörnwall在您的#2中,{reply,{text,Message}…将通过websocket发送,而不是发送websocket处理程序消息的Ref?