3

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

4

3 回答 3

2

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

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

将 Pid 发送到 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}.
于 2013-03-29T15:31:48.587 回答
1

搞定了!!!使用 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
于 2013-04-08T01:57:02.060 回答
0

这将需要一种涉及内存存储的综合方法。例如,每个用户可能有一个进程持有套接字连接,因此,您可以在 中保存mnesia一条ets table记录,例如:#connected_user{pid = Pid,username = Username,other_params = []}

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

于 2013-03-29T09:32:13.990 回答