Hi, I’m using Phoenix channels and am curious if I’m using them in a way that is common/correct.
I understand you’ve got the “channel”, which is a connection between a client (say a browser) and the server. And then a client can subscribe to one or many “topics” over the channel. And then the client can send “messages” regarding a topic.
For my use case, I have users that can subscribe to many topics (without authorization, simply having the topic id is good enough). The topics use the “topic:subtopic” format implied in the docs as being a useful pattern.
My topics are of the format “room:id” where id is unique and random.
In my Phoenix.Channel module I’ve parsed out requests to join particular rooms with something like:
Thanks @kokolegorille, got it. So a single socket connection multiplexes multiple channels. And channels have multiple topics.
How am I doing otherwise for my implementation of topics? Is parsing out the room id in Phoenix.Channel.join/3 the way to go? Or should it be done in the Phoenix.Socket channel macro, something like:
defmodule AppWeb.UserSocket do
use Phoenix.Socket
## Channels
channel "room:*", AppWeb.RoomChannel
Parsing out the room ID there is great. I do that often. I typically parse it out in the join and put it into the assigns for use in any channel callbacks. This allows makes it a bit easier to work with.
A socket is the connection. Each socket routes specified topics to the appropriate Channel handler (Via your channel function calls in the socket module). I personally think of it as 2 physical concepts with 3 layers involved (one layer of extra abstraction). At the end of the day, the topic is literally a key in a map linking the string topic to a particular channel. From a technical perspective, you can’t have 2 of the same topic under 1 socket (maps have unique keys).