如果用户已加入主题,说"rooms:lobby"
,然后用户加入同一频道上的另一个子主题,如"rooms:party"
。我如何强制用户从后端离开“房间:大厅”。我尝试过滤广播,但没有任何运气。我宁愿通过过滤广播来终止与旧的子主题的连接。Phoenix:一次只允许订阅一个频道上的一个子主题
defmodule MyApp.RoomsChannel do
use Phoenix.Channel
intercept ["new_msg"]
def join("rooms:" <> room_id, _params, socket) do
{:ok, assign(socket, :room_id, room_id)
end
def handle_out("new_msg", payload, socket) do
if current_room?(socket.assigns[:room_id], socket.topic) do
push socket, "new_msg", payload
{:noreply,socket}
else
{:noreply, socket}
end
end
defp current_room?(room_id, "rooms:" <> sub_topic) do
room_id == sub_topic
end
end
我知道这是可以从前端离开的话题,但我需要确保只有他们正在查看自己当前主题得到有效载荷,而不是任何以前的主题,其中订阅了一特定频道。
我不知道我按照你的问题。每个主题将在不同的过程中以不同的渠道运行。因此,考虑到上面的代码,如果您使用的是“房间:1”和“房间:3”,即使它们使用相同的逻辑,它们也会完全分开。所以如果你想让用户离开,你可以返回来自任何事件的'{:stop,:normal,:ok,:state}'或类似的东西。 –
让我给出更多的上下文。该应用程序正被用于推送通过RPC从Rails应用程序发送到通过反应/流量构建的SPA的通知。如果这是一个香草请求/响应REST应用程序,更改路由将重新加载页面并更新套接字连接,则使用正确的ID加入子主题。我假设在这一点上旧的连接和主题订阅将会丢失。我试图通过SPA上的路线更改实现相同的行为。 –
我用'gen_server'解决了这个问题,它跟踪最近加入的子主题,然后在'handle_out'中发送一个离开事件,告诉客户端离开它是一个旧的子主题,而不是原来的有效载荷。这感觉喜欢它不是处理这个最合适的方法。 –