
Phoenix WebSockets under a Microscope - zorbash
https://zorbash.com/post/phoenix-websockets-under-a-microscope/
======
chrismccord
Phoenix creator here. Happy to answer any questions. This article does an
excellent job diving into the underlying details of Phoenix channels and
pubsub.

For those that want a thousand foot view and are curious what makes Elixir and
Phoenix unique compared to other solutions, think of Phoenix channels as
trivial realtime communication that is distributed out of the box. With
Elixir, processes (green threads) are load balanced on both IO and CPU so no
single channel client will block another, regardless of the work you may be
doing. Channels are also multiplexed on a single concrete connection so the
same client can be doing intensive work in one channel while receiving
messages over another. The runtime is also distributed, so process messages
can reach any server in the cluster which is what allows you to
`broadcast(socket, "event", msg)` in a channel and it Just Works across the
cluster.

~~~
sudhirj
Thanks a ton for Phoenix :D Re the clustering support, I can see in your
article here [https://dockyard.com/blog/2016/01/28/running-elixir-and-
phoe...](https://dockyard.com/blog/2016/01/28/running-elixir-and-phoenix-
projects-on-a-cluster-of-nodes) that the Erlang VM joins clusters on startup -
any idea if it's easy or possible to dynamically join and leave clusters?

Sort of what you'd expect in a cloud environment: one or two bastion servers
would have a known IP address, and the remaining would be expected to learn
about the cluster when the joined with the bastions.

~~~
notamy
> any idea if it's easy or possible to dynamically join and leave clusters?

Don't know the specifics in Erlang, but in Elixir you can just use
Node.connect/1 and Node.set_cookie/2:
[https://hexdocs.pm/elixir/Node.html](https://hexdocs.pm/elixir/Node.html)

Edit: There's also stuff like libcluster
([https://github.com/bitwalker/libcluster](https://github.com/bitwalker/libcluster))
that allow for this at a higher level afaik.

~~~
zorbash
We are happy users of libcluster but there's also
[https://github.com/mrluc/peerage](https://github.com/mrluc/peerage) for
automatic node discovery.

------
sb8244
One of the highlights for Phoenix WebSockets came from the insights of one of
my co-workers. I was having a problem where I only wanted to send websocket
traffic up to 1 time every 3s (debounced essentially). I was struggling with
this solution and came up with a hacky solution that would debounce on the
event broadcast side (vs the socket side). This means it would be up to 1 time
every N seconds per server.

Co-worker showed me that sockets are just processes, and that once the process
exists, I can treat it like any other process. We wrote a fairly simple state
machine for debouncing, and made it debounced on the socket side. It's awesome
because it's debounced even in a distributed setup. Less than 25 lines of code
for all of that!

~~~
zorbash
For some channels / topics I let the clients provide a `refresh_interval`
parameter upon joining to tackle similar problems. I'm also curious to see
your state machine, maybe it's something worth extracting to a middleware.

~~~
sb8244
Put it up on a gist for HN
[https://gist.github.com/sb8244/e6884ad08d91de8c4aa5bf3241855...](https://gist.github.com/sb8244/e6884ad08d91de8c4aa5bf32418557e1)

------
exabrial
The wsta is something I've been needing! It's like wget or curl for
websockets!

~~~
jaux
+1 for wsta! I am using dwst, but a cli tool can be handy from time to time.

------
d3ckard
Most awesome thing is that everything is opt-in. You don't want the channel
mechanism? No problem, just write a handler yourself with your own logic and
quirks. Here is a short tutorial on this:
[http://benjamintan.io/blog/2014/02/12/phoenix-elixir-web-
fra...](http://benjamintan.io/blog/2014/02/12/phoenix-elixir-web-framework-
and-websockets/)

At the same time, if channels fit what you want to do, they're awesome. Adding
collaborative editing is super easy.

------
slagfart
Just to highlight - this is in no way related to the existing Apache Phoenix
project, or to the ten other tech projects also called Phoenix.
([https://en.wikipedia.org/wiki/Phoenix#Computing](https://en.wikipedia.org/wiki/Phoenix#Computing))
This is a new one.

~~~
swsieber
Well, relatively new. It was actually the one I was expecting when I clicked
through (the Erlang/Elixir web framework). Give it had websockets in the
title, I would have been surprised if it wasn't.

I'm surprised that any hacker news reader would actually think anything else,
given how often this particular Phoenix has surfaced here.

