我正在使用 yaws(Erlang 框架)进行套接字通信。我可以使用websocket_send从服务器将消息发送回用户,但是我需要指定用户的 PID,这意味着我可以将消息发送回该用户。但是,我想向所有连接的用户发送消息。有什么办法吗?
3 回答
每次建立 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}.
搞定了!!!使用 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
这将需要一种涉及内存存储的综合方法。例如,每个用户可能有一个进程持有套接字连接,因此,您可以在 中保存mnesia
一条ets table
记录,例如:#connected_user{pid = Pid,username = Username,other_params = []}
。
稍后在加深对这个问题的认识之后,您将转向会话管理、如何处理离线消息,以及最重要的presence
. 无论如何,当一条消息进入时,具有目标用户名,然后您将从我们的表中查找并获取相应的Pid
,然后将这条消息发送给它,然后它会通过它的实时 Web Socket 发送它。