Configure channel presence tracking and subscription separately


I would like, for a given websocket/channel connexion, be able to listen to presence messages and to track the socket, but opt-in both of these features separately.

This is from the docs :

  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(:second))
    {:noreply, socket}

If I want neither presence info nor be tracked, I will just not call the code.
If I want both, I will call this code.
If I want to be tracked but not provide the presence data, I will call this code, but also not push presence_state, and intercept presence_diff and discard it (no push).

But what if I want not be tracked, but receive presence_diff messages ?

Thank you.

I guess I’ll have to implement Phoenix.Tracker behaviour and subscribe to my presence process or to my behaviour implementation process depending on what features I want to provide for the current connection.

Phoenix.PubSub.subscribe(socket.pubsub_server, socket.topic), now await your diff messages :slight_smile:

1 Like

Thanks @chrismccord

Phoenix.PubSub.subscribe(socket.pubsub_server, socket.topic)

That looks like subscribing the channel process to its own topic, but bypassing all the phoenix channel code. So all channel messages will sent through the wire but also (duplicated) received in handle_info, where I can select those diffs and push them “manually”. Am I right ?

Err sorry, yes that was incorrect. PubSub.subscribe(socket.pubsub_server, topic)*. You can subscribe to the presence diffs pass passing the channel topic of whatever you care about listening to. If you are wanting to receive diffs on the same channel topic but not be tracked, don’t call Presence.track. You are already subscribed to the topic by joining the channel so you will receive the messages. (Presence.track(socket) simply does Presence.track(socket.topic)

1 Like

Oh, that means that for any channel, if anyone calls Presence.track then every other topic subscriber will receive presence diff even if they did not call track.

I’ll test this solutions then, thank you very much. This is more simple than I thought :slight_smile:

1 Like

It works well :slight_smile: