Is it possible to create topics dynamically in Phoenix

I am new to Phoenix. I was wondering if it is possible to create topics dynamically in Phoenix.
From what I understood till now in Phoenix if a user joins a topic they get all the messages sent on that topic. What if I want add a functionality in which user can create own topic and then send messages on it. Is that possible ?

4 Likes

Thats totally possible, so in the user_socket.ex file you add a room as "room:name:*". Just add whatever you want after the star when joining the channel and boom your off.

For example I have a team channel defined like :

channel("team:*", TpPhoenixWeb.RequestCounterChannel)

The user then joins a channel named "team:API_KEY_HERE" and only they can see what is broadcast there.

6 Likes

But can these topics be created on the go. As in without being written in user_socket.ex in the start ?

3 Likes

You would need a macro that dynamically creates user_socket.ex based on input provided to the macro.

3 Likes

To be clear, what the macros in user_socket do is route topics that have a particular prefix to a particular channel module. You could make a generic one:

channel "generic:*", GenericChannel

Then you can put literally anything after generic:

5 Likes

I believe that you can meaningfully accomplish this task without creating a macro as specified by @benwilson512 above. And in general if you can accomplish something with just modules and functions then use that approach. Quoth the Elixir docs: “Macros should only be used as a last resort”.

4 Likes

Yes, I think that whatever use case the OP has should be covered by using the method provided by @benwilson512.

2 Likes

How do we join multiple topics in phoenix.js? Looking at the source, I see it supports only 1 topic per channel, while the docs states, “the client may join any number of topics on any number of channels”.

1 Like

Joining multiple topics can be accomplished by calling socket.join multiple times, this will create multiple channels multiplexed over the same socket. Here’s an example:

let socket = new Socket("/socket", {params: {userToken: "123"}})
socket.connect()

let channel1 = socket.channel("room:123", {token: roomToken})

channel1.join()
  .receive("ok", ({messages}) => console.log("catching up", messages) )
  .receive("error", ({reason}) => console.log("failed join", reason) )
  .receive("timeout", () => console.log("Networking issue. Still waiting..."))

let channel2 = socket.channel("room:456", {token: roomToken})

channel2.join()
  .receive("ok", ({messages}) => console.log("catching up", messages) )
  .receive("error", ({reason}) => console.log("failed join", reason) )
  .receive("timeout", () => console.log("Networking issue. Still waiting..."))

Since joining multiple topics as a client is a different topic than creating dynamic topics as the server, if you still have questions it’s probably better to continue the discussion in a separate post.

1 Like