2015-12-30 104 views
1

如果用戶已加入主題,說"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

我不知道我按照你的問題。每個主題將在不同的過程中以不同的渠道運行。因此,考慮到上面的代碼,如果您使用的是「房間:1」和「房間:3」,即使它們使用相同的邏輯,它們也會完全分開。所以如果你想讓用戶離開,你可以返回來自任何事件的'{:stop,:normal,:ok,:state}'或類似的東西。 –

+0

讓我給出更多的上下文。該應用程序正被用於推送通過RPC從Rails應用程序發送到通過反應/流量構建的SPA的通知。如果這是一個香草請求/響應REST應用程序,更改路由將重新加載頁面並更新套接字連接,則使用正確的ID加入子主題。我假設在這一點上舊的連接和主題訂閱將會丟失。我試圖通過SPA上的路線更改實現相同的行爲。 –

+0

我用'gen_server'解決了這個問題,它跟蹤最近加入的子主題,然後在'handle_out'中發送一個離開事件,告訴客戶端離開它是一箇舊的子主題,而不是原來的有效載荷。這感覺喜歡它不是處理這個最合適的方法。 –

回答

1

從您的評論中可以看出,您嘗試每條路線加入1個頻道,並且您希望在路線改變時切換頻道而不是累積多個頻道。我猜你是從高級React組件中加入生命週期方法(例如ComponentWillMount)中的通道。

如果是這樣,爲什麼不在ComponentWillUnmount中終止客戶端的通道?這應該在您的客戶端路由更改之前觸發。

+0

我最終做了類似的事情,在路由器轉換回調中添加了'join'和'leave'。 –