axelson

axelson

Scenic Core Team

How can you modularize a Phoenix Channel

I’m struggling with how to sustainably organize a Phoenix Channel. Even with the concept/design of “Phoenix Is Not Your Application” I find my channels growing very large as the number of potential messages sent to or from a channel increases.

I’ve sometimes wished for a “routing” mechanism similar to HTTP but specific to a channel. So that certain prefixes of incoming channel messages could be handled in a consistent way. Alternatively I may want to just create more channels to spread out the messages, but then the clients need to join multiple channels when they connect to the socket. Which isn’t a huge burden (and is fine performance-wise since subscriptions are cheap), but feels like unneeded complexity.

How have others tackled this issue? Or is it a non-issue?

Most Liked

axelson

axelson

Scenic Core Team

For anyone stumbling on this post now I’d recommend trying out this library that is made to modularize a Phoenix Channel:

https://github.com/doorgan/channel_handler

chrismccord

chrismccord

Creator of Phoenix

Can you share your current channel code? it would be easier to say more if we have a real example to discuss. Thanks!

yurko

yurko

With full blown WebSocket APIs I also dislike them getting too big so I split them into sub-channels with a tiny bit of pattern matching, this way I can have the handlers separate (they still don’t do anything but delegate to context services), that keeps the files reasonably small.

Here is an example of a channel that delegates to subtopics:

alias App.Service.Channel.{Faq, Learning, Search} # etc

  # join clauses
  
  def handle_in("faq:" <> msg, payload, socket), do: Faq.process_message(msg, payload, socket)

  def handle_in("learning:" <> msg, payload, socket), do: Learning.process_message(msg, payload, socket)

  def handle_in("search:" <> msg, payload, socket), do: Search.process_message(msg, payload, socket)

 # etc

Frontend can then send a message such as search:find with some payload, the channel will process it and call process_message in Search service with find message.

Where Next?

Popular in Questions Top

jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New

We're in Beta

About us Mission Statement