forte

forte

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:

  def join("room:" <> room_id, _message, socket) do
    %{ topic: "room:" <> room_id } = socket
    Store.get_initial_state(room_id)
    ...

And looked up the initial room state to send back to the client based on the room_id.

Then when handling messages regarding a particluar room, I parse out the particular room in question with something like:

  def handle_in("state_change:update_guests", %{"body" => body}, socket) do
    %{ topic: "room:" <> room_id } = socket
    Store.update_guests(room_id, body)
    broadcast!(socket, "state_change:update_guests", %{body: body})
    ...

Is this the correct way to deal with N unique subtopics? It works, but is there a better way? Should I be using socket "id"s?

Thanks.

Showing Posts 1 to 3

kokolegorille

kokolegorille

Hello and welcome,

It’s the socket which is the connection, and You can multiplex many (really many) channels on it.

Under the hood, channels use distributed pubsub system.

Typical channel’s names I use

system
user:id
room:id
lobby

etc.

BTW the site uses Markdown, and if You put code, it’s better to enclose it between ```

forte

forte OP

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

Thanks.

sb8244

sb8244

Author of Real-Time Phoenix

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).

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New
thiagogsr
** (ArgumentError) expected :max_attempts to be a positive integer, got: {:@, [line: 10, column: 19], [{:max_attempts, [line: 10, column:...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews