Hi
I have a messaging app where users can have many different conversations.
Ideally I’d from the client just connect/join the Phoenix socket once, instead of having to
manually join each conversation channel (there can potentially be 10s or 100s).
For that, I was thinking of doing something like this inside the Socket connect/2
callback
ids =
user
|> Conversaiton.get_user_conversations
|> Enum.map(fn conversation -> conversation.id end)
for id <- ids, do: MyApp.Endpoint.subscribe("conversations" <> id)
And then dynamically subscribe the socket to any new conversations that would be created.
My question is how much overhead there is for these subscriptions and if I will run into performance problems
2 Likes
You can’t subscribe in UserSocket.connect since it’s in the transport process. To get what you want, have a UserChannel with topic user:[user_id]
. You could then multiplex conversations by subscribing the channel join to conversation:[convo_id]
Subscriptions are ets entries, so they are very cheap. Additionally, we pool the pubsub servers, so the underlying genserver call for subscribe is pooled.
3 Likes
I do what chrismccord stated in my work project to have a restricted set of user channels over a single socket internally get messages and handle upwards of a hundred ‘topics’ in just those couple of channels, it works really well. We do have a restricted set of people that will use the system though, a few thousand at most.
1 Like