我正在尝试将 Phoenix Channels 用作极其简单的游戏服务器。对于原型,其唯一目的是同步玩家位置。但是,在此之前,每个客户端都必须知道所有其他客户端的存在。
当一个新客户加入房间时,我将其广播给所有在场的客户RoomChannel
:
@impl true
def join("room:main", _payload, socket) do
send(self(), :after_join)
{:ok, socket}
end
@impl true
def handle_info(:after_join, socket) do
broadcast_from!(socket, "user_join", %{user_id: socket.assigns.user_id})
{:noreply, socket}
end
这些现有的客户端对消息做出反应并产生一个新的玩家对象。但是,新用户不知道房间里还有谁,因为他们是最后加入的,并且没有收到任何此类信息。我正在努力纠正这一点。
我的计划是将我的代码修改为如下内容:
@impl true
def join("room:main", _payload, socket) do
Agent.update(active_users_agent, fn(list) -> [list | socket.assigns.user_id] end, 5000)
send(self(), :after_join)
{:ok, socket}
end
@impl true
def handle_info(:after_join, socket) do
push(socket, "room_data", Agent.get(active_users_agent, fn(list) -> list end))
broadcast_from!(socket, "user_join", %{user_id: socket.assigns.user_id})
{:noreply, socket}
end
换句话说,我想维护一个加入用户的列表,并在加入时将其发送给新用户(并将它们添加到其中)。我是否使用代理、GenServer 或其他东西都无关紧要。
问题是,我不知道在哪里可以初始化那个代理,因为我RoomChannel
没有init()
回调;也不如何将它传递给join()
andhandle_info()
回调。什么是有效的——或者更好的,惯用的——方法来做到这一点?
PS值得注意的是,我希望将其存储在内存中,而不是数据库中。