websocket - 我可以选择通过 Phoenix Presence 跟踪的特定进程/套接字吗?
问题描述
我的用例是让多个用户连接到大厅/等候室,但只有两个用户会从大厅中被选中来开始对话,之后他们应该从大厅中移除。我该如何实施?请注意,在此系统中,用户没有注册,也没有用户名。他们应该直接从网页进来。
显然track
anduntrack
函数也有接受pid
作为参数的变体。但是,当需要开始对话时,我不确定如何首先检索进程的 pid。
在这种情况下,该功能self()
是否正确?即也许我可以写
def handle_info(:after_lobby_join, socket) do
Presence.track(socket, "lobby", %{
pid: self()
})
{:noreply, socket}
end
def handle_info(:start, socket) do
pid1 = hd(Presence.list(socket)["lobby"][:metas])[:pid]
# Start the conversation by sending messages individually to pid1 and pid2
...
untrack(pid1, "my_app:lobby", "lobby")
{:ok, socket}
end
或者我是否使问题过于复杂/没有正确理解存在?
还有一个phx_ref
字段,但我似乎无法将其用于此目的。
此外,显然我只想向"start_conversation"
被选中的两个用户发送消息,而不是大厅中的其他用户。我看到该函数push
将消息发送到指定的套接字。但是,如果我在跟踪 pid,是否可以从 pid 中识别出相应的套接字?
解决方案
我最终使用个人用户渠道解决了我最初的问题。我只是让前端生成随机用户 ID。
Elixir 论坛提出了一个不使用用户频道的解决方案。它虽然不使用存在。
def handle_info({:new_user, socket}, [{us1, ref1}, {us2, ref2}]) do
# we had 2 users, a new one joined, so that's 3
user_sockets = [socket, us1, us2]
# we can create a room for them now
create_new_room(user_sockets)
# and clean the state
Enum.each([ref1, ref2], fn ref ->
Process.demonitor(ref)
end)
{:noreply, []}
end
def handle_info({:new_user, socket}, waiting_user_sockets) do
# otherwise just add the new users to the waiting users list
ref = Process.monitor(socket)
{:noreply, [{socket, ref} | waiting_user_sockets]}
end
def handle_info({:DOWN, ref, :process, _object, _reason}, waiting_user_sockets) do
# remove the disconnected socket
end