Counting connections to a Phoenix Channel
I was unable to find a quick Google answer to this question, so I thought I should post the “dirty” solution I found:
Realistically you can only count the subscribers to your local node unless
there is some clever way for connected nodes to return their subscriber count,
which I have not come across (This might be useless anyways as subscribers may
have left by the time you get the count back). By default Phoenix stores the PID
s of any
subscribers inside an ets
table (I believe you can also use Redis). As a result
we can just query the ets
table directly. The naming convention for the table is
APP_NAME.PubSub.Local0
.
Ex:
:ets.info(ExometerPhoenixChannelDemo.PubSub.Local0)
returns
[read_concurrency: true, write_concurrency: true, compressed: false,
memory: 1603, owner: #PID<0.285.0>, heir: :none,
name: ExometerPhoenixChannelDemo.PubSub.Local0, size: 14, node: :nonode@nohost,
named_table: true, type: :duplicate_bag, keypos: 1, protection: :public]
All you would need to do then is extract the size
key to get a total.
More useful would be get the count of connections per Phoenix topic - this you
can do with another ets
function ets.foldl/3
which you need to pass a function.
Here is an example function that will count all the subscribers per topic:
def count do
acc = fn {channel, _}, map -> Map.update(map, channel, 1, &(&1 + 1)) end
:ets.foldl(acc, %{}, ExometerPhoenixChannelDemo.PubSub.Local0)
end
This returns something akin to:
%{"phoenix:live_reload" => 2, "stats:erlang_memory_atom" => 2,
"stats:erlang_memory_binary" => 2, "stats:erlang_memory_ets" => 2,
"stats:erlang_memory_processes" => 2, "stats:erlang_memory_total" => 2,
"stats:socket_connections_count" => 2}
You can see that I have two browsers open with a connection to each topic.
Please note: Cowboy times out web socket connections after 30 seconds if they no longer respond, so statistics are inaccurate for 30 seconds at a time.