0

Is there a relatively simple, documented way in a Phoenix application to read how many active sockets and channels are currently open at any given time? And more specifically, is it possible to filter this data by topic and other channel connection metadata?

My use case is for analytics on active connections to my backend.

Thanks for any suggestions!

Murcielago
  • 1,030
  • 1
  • 14
  • 24

1 Answers1

1

You are looking for Phoenix.Presence. From the documentation:

Provides Presence tracking to processes and channels.

This behaviour provides presence features such as fetching presences for a given topic, as well as handling diffs of join and leave events as they occur in real-time. Using this module defines a supervisor and allows the calling module to implement the Phoenix.Tracker behaviour which starts a tracker process to handle presence information.

Basically, you are supposed to implement Phoenix.Presence behaviour (the almost ready-to-go example is there in docs,) and Phoenix.Tracker according to your needs.

Community
  • 1
  • 1
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • Thanks, I've read through the `Presence` docs and it seems like it's intended for tracking presences **by topic**. However, if I have various different topics that belong to the same category (e.g. `user:1`, `user:2`) is it possible to track presence for the `user` category? I haven't seen anything in docs indicating this. – Murcielago Nov 22 '18 at 23:55
  • You are to implement your own logic tracking whatever you need. – Aleksei Matiushkin Nov 23 '18 at 03:21
  • I was able to solve this problem by creating a designated `main` channel that all users connect to in addition to connecting to their own user channel (e.g. `user:23`). I then intercepted events like `presence_diff` in the `main` channel and sent updates only to admins, as regular users should not be able to see presence information of other users, at least as analytics is concerned in my app. I still feel like this solution is kind of a workaround and that a better solution is available, but I haven't been able to find any documented examples of similar things. – Murcielago Dec 10 '18 at 20:47
  • Do you know of any examples of implementations of custom tracker logic? – Murcielago Dec 10 '18 at 20:49
  • Unfortunately, I was never in a need to implement this. I am positive though the implementation should not be hard if tried instead of looking for the ready-to-go solution. – Aleksei Matiushkin Dec 11 '18 at 05:37
  • 1
    @Murcielago have a look at my repo, although this was my first stab at implementing a tracker https://github.com/denvaar/mmo_server/blob/master/lib/adventure_server_web/channels/player_tracker.ex – denvaar Feb 24 '19 at 02:55
  • @denvaar - this looks really cool. I just glanced in the channels folder. I'll take a deeper look later. Thanks a lot for sharing :) – Murcielago Feb 25 '19 at 03:19
  • 1
    Phoenix stores socket information in `ets`. There is a great article about reading that information http://neuvians.io/2016/02/27/counting-connections-to-a-phoenix-channel/ The code is pretty short: ` def count do acc = fn {channel, _}, map -> Map.update(map, channel, 1, &(&1 + 1)) end :ets.foldl(acc, %{}, MyGreatApp.PubSub.Local0) end ` – Victor Ivanov Apr 14 '19 at 22:32