2016-08-05 5 views
1

WebSocket接続で私のElixirアプリケーションにPhoenixフレームワークを使用します。私は、ユーザー用と管理者用の2つの異なるトピックを持っています。管理者は、どのユーザーがいるかを確認する必要があります。私はフェニックスのPresenceモジュールを使用することに決めました。残念ながら、トラッキングを開始するソケットにのみ現在の状態のPresenceを送信することができます。異なるトピックからユーザーの存在を追跡することは可能ですか?

例コード:

def join("users", params, socket) do 
    socket |> assign(:user_id, params[:user_id]) 

    send(self, :after_join) 
    {:ok, socket} 
end 

def join("admins", _params, socket) do 
    {:ok, socket} 
end 

def handle_info(:after_join, socket) do 
    push(socket, "presence_state", Presence.list(socket)) 

    {:ok, _} = Presence.track(socket, socket.assigns[:user_id], %{ 
    online_at: inspect(System.system_time(:seconds)) 
    }) 

    {:noreply, socket} 
end 

私は、プレゼンスの変更について管理者フロントエンド・アプリケーションでのイベントをリッスンします。 Phoenix.Presenceでそれを行うことは可能ですか?

答えて

3

あなたはYourApp.Endpoint.broadcast/3を使用することができます。

def handle_info(:after_join, socket) do 

    {:ok, _} = Presence.track(socket, socket.assigns[:user_id], %{ 
    online_at: inspect(System.system_time(:seconds)) 
    }) 
    YourApp.Endpoint.broadcast "admins", "presence_state", Presence.list(socket) 

    {:noreply, socket} 
end 

とあなたのadminChannelからpresence_stateを聞く:

adminChannel.on("presence_state", state => { 
    presences = Presence.syncState(state) 
    // doSomethingWithPresences 
} 

クライアントがpresence_diff event.Youを受け取るときあなたはYourApp.AdminChannelYourApp.UserChannel

を分ける必要がありますプッシュすることができますそれをユーザーチャネルに送信し、Endpoint.broadcast/3を再度使用してください。

userChannel.on("presence_diff", diff => { 
    userChannel.push("presence_diff", diff) 
} 
YourApp.UserChannel

def handle_in("presence_diff", diff, socket) do 
    YourApp.Endpoint.broadcast "admins", "presence_diff", diff 
    {:noreply, socket} 
end 

そして今、あなたはあなたのpresence_diffイベントを聞くことができます。

adminChannel.on("presence_diff", diff => { 
    presences = Presence.syncDiff(diff) 
    render(presences) 
} 
+0

これは参考になりました。 「presence_diff」イベントの処理方法を知っていますか?ユーザーがチャンネルに接続したときにプレゼンスが得られますが、管理者が後でそのユーザーをログに記録すると、彼は空のプレゼンス状態を受け取ります。 – mirox

+0

私は答えを編集しました。助けを願う – TheAnh

+0

私はあなたの考えを試して、それはうまくいかない。ユーザーがプレゼンスをログアウトすると、admin watchは更新されません。 1人のユーザーがオンラインになったときに起こります。存在感の違いについて管理者に通知する他のユーザーはいません。私はそれを掘り出すでしょう、あなたがチャンネルポッドを持っているなら、その存在を追跡しているのを見ました:https://hexdocs.pm/phoenix/Phoenix.Presence.html#c:track/4を見てください。だから私はチャンネルをpidにする必要があります。 – mirox

1

は、次のようなチャネルのコールバックハンドラの1つ(内追跡プレゼンスを設定する場合handle_info/2)、次のような任意のトピックにトラッキングを追加できます。

そのプロセスは presence_diffメッセージの受信を開始しますその時点で

YourApp.Endpoint.subscribe("admins")、:

Presence.track(self(), "admins", socket.assigns[:user_id], %{some_metadata: "whatever"})

その後、別の場所で別のプロセスでは次のようなadminsトピックをサブスクライブすることができます。

関連する問題