【问题标题】:Yaws websocket send message to all connected usersYaws websocket 向所有连接的用户发送消息
【发布时间】:2013-03-19 23:39:52
【问题描述】:

我正在使用 yaws(Erlang 框架)进行套接字通信。我可以使用 websocket_send 从服务器将消息发送回用户,但是我需要指定用户的 PID,这意味着我可以将消息发送回该用户。但是,我想向所有连接的用户发送消息。有什么办法吗?

【问题讨论】:

    标签: erlang websocket yaws


    【解决方案1】:

    每次建立 websocket 连接时,都会为该连接创建一个新的 gen_server 进程。因此,这些服务器中的每一个都对应一个 websocket 连接。因此 websocket_send 需要 gen_server 的 PID。

    要向所有连接的客户端发送消息,您需要维护所有 gen_servers 的 PID。这可以通过拥有自己的 gen_server 或使用 ets 来完成。

    类似于sending the Pid to gen_server 您可以在 websocket 回调初始化函数中发送 Pid

    init(Args) ->
      gen_server:cast(?YOURSERVER,{connection_open, self()}),
      {ok, []}.
    

    终止期间

    terminate(Reason, State) ->
      gen_server:cast(?YOURSERVER,{connection_close, self()}).
    

    您的 gen_server handle_cast 可能如下所示

    handle_cast({connection_open, Pid}, Pids) ->
          {noreply, [Pid | Pids]};
    handle_cast({connection_close, Pid}, Pids) ->
          {noreply, lists:delete(Pid, Pids)};
    handle_cast({send_to_all, Msg}, Pids) ->
          [yaws_api:websocket_send(Pid, Msg) || Pid <- Pids, is_process_alive(Pid)],
          {noreply, Pids}.
    

    【讨论】:

    • 感谢 vinod 的回复。如何为此目的使用消息队列。因此,所有用户都使用一个队列连接,当一个用户发布消息时,它会通过 yaws 进入 erlang 模块,然后将其发布到 rabbitMQ 并发布给所有用户???
    • 如果您使用消息队列,那么最好通过它进行路由。但是,如果您打算仅将其用于此目的,则可能会产生开销。 yaws 创建的每个 gen_server 都应该注册到频道。然后它可以在handle_info中接收消息,您可以在其中执行yaws_api:websocket_send(self(), Msg)
    • 嗨 Vinod.. 我对 erlang 很陌生,所以你有任何使用 ETS 的示例代码
    【解决方案2】:

    成功了!!!使用 GProc :)

    Gproc 是 Erlang 的进程字典,它提供了许多超出内置字典所具有的有用功能:

    Use any term as a process alias
    
    Register a process under several aliases
    
    Non-unique properties can be registered simultaneously by many processes
    
    QLC and match specification interface for efficient queries on the dictionary
    
    Await registration, let's you wait until a process registers itself
    
    Atomically give away registered names and properties to another process
    
    Counters, and aggregated counters, which automatically maintain the total of all counters with a given name
    
    Global registry, with all the above functions applied to a network of nodes
    

    【讨论】:

      【解决方案3】:

      这将需要一种涉及内存存储的综合方法。例如,每个用户都可能有一个进程持有套接字连接,因此,你可以说,mnesiaets table 等。像这样的记录:#connected_user{pid = Pid,username = Username,other_params = []}

      稍后在加深对这个问题的认识之后,您将转到会话管理,如何处理离线消息,最重要的是 presence。无论如何,当一条消息进入时,具有目标用户名,然后您将从我们的表中进行查找并获取相应的Pid,然后将这条消息发送给它,然后它会通过它的实时网络发送它插座。

      【讨论】:

      • 嗯.. 为此目的使用消息队列怎么样。因此,所有用户都使用一个队列连接,当一个用户发布消息时,它会通过 yaws 进入 erlang 模块,然后将其发布到 rabbitMQ 并发布给所有用户???
      猜你喜欢
      • 2013-04-23
      • 1970-01-01
      • 2016-12-12
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多