Phoenix:一次只允许订阅一个频道上的一个子主题
Phoenix: Only allow subscription to one sub topic on a channel at a time
如果用户加入了一个主题,说 "rooms:lobby"
然后用户在同一频道加入另一个子主题,例如 "rooms:party"
。如何强制用户从后端离开 "rooms:lobby"。我试过过滤广播,但没有成功。我更愿意终止与旧子主题的连接而不是过滤广播。
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 个频道,并且您想在路线更改时切换频道,而不是累积多个频道。我的猜测是您正在从高级 React 组件的生命周期方法(例如 ComponentWillMount)中加入频道。
如果是这样,为什么不在 ComponentWillUnmount 中终止来自客户端的通道?这应该在您的客户端上的路由更改之前触发。
如果用户加入了一个主题,说 "rooms:lobby"
然后用户在同一频道加入另一个子主题,例如 "rooms:party"
。如何强制用户从后端离开 "rooms:lobby"。我试过过滤广播,但没有成功。我更愿意终止与旧子主题的连接而不是过滤广播。
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 个频道,并且您想在路线更改时切换频道,而不是累积多个频道。我的猜测是您正在从高级 React 组件的生命周期方法(例如 ComponentWillMount)中加入频道。
如果是这样,为什么不在 ComponentWillUnmount 中终止来自客户端的通道?这应该在您的客户端上的路由更改之前触发。