Channels/sockets without Phoenix?

Hi,

I’m writing a simple web app written in HTML + JS that posts data via AJAX to a Cowboy/Plug Elixir server.

I want the server to also send unrequested updates to the web client (i.e. messages, notifications…) without Phoenix. Not for any special reason, just that I’d like to know if it’s possible, learn the underlying principles before diving into Phoenix, and also keeping it as minimal as possible.

If it’s going to be a big hassle, I’ll go with Phoenix. However, I’d like to know if it’s worth trying to do it without Phoenix. Right now I have a minimal Plug.Router which is enough for me and I’d like to keep it minimal if possible.

Thanks!

3 Likes

You could certainly make it work without Phoenix, but I don’t think it’s worth it. IIRC, Plug doesn’t support installing custom Cowboy handlers, so you’d have to hack a bit around it (I think Phoenix can serve as an example). Then you could install websocket handlers and it would basically work.

In terms of LOC, it probably wouldn’t be too big, maybe in lower hundreds, but it would definitely be inferior to what Phoenix gives you. As I mentioned in my blog, Phoenix is modular, so you can slice it down as much as you please. If you want websockets, you’d need only router, and can skip most of other stuff (controllers, views, templates, JS).

To summarize, personally I’d just use Phoenix for the job :slight_smile:

6 Likes

@sasajuric is correct, you wouldn’t want do that by yourself.

You can do even simpler by adding only websockt handler into pure elixir mix project, like this :


or this :

but again, phoenix provided them all in really simple & elegant way, and still performance.

2 Likes

Also note that on the client and server you’ll have to roll the following yourself:

  • handling disconnects and reconnects – websockets don’t do this for you automatically
  • handling the websocket process crashing the server and notifying the client. Have the client automatically reestablishing and recover with exponential backoff
  • authenticate/authorize clients connections
  • likely multiplex multiple “channels” of communication
  • fallback to long polling if websockets is not available
  • if falling back to long polling, avoid needing sticky sessions
  • handling request/response style messaging such as channel.push("event").receive("ok", resp => ...)
  • likely build out a pubsub layer if you want to notify multiple clients of certain happenings
  • if you need a pubsub layer, support multinode communication

Building these things out on your own would be a great learning experience, but we solve the problems you need out of the box and as Saša said, you Phoenix is modular so you can pick and choose what you’d like. Hope that helps!

8 Likes

@chrismccord Do you have any plan to split phoenix_channel into a standalone application? Maybe I have same problems with @cfenollosa . A realtime channel is enough for me and I don’t want to import unneeded packages such as ecto, templates and so on.

No, since you need a webserver to make channels work with our default transports (WebSocket and LongPolling). If you don’t want HTML templates or Ecto, no problem: mix phoenix.new my_app --no-ecto --no-html. Problem solved :slight_smile:

13 Likes

A post was split to a new topic: Websockets and communicating to other languages

@chrismccord does Pheonix has published its data transfer protocol? I’m also planning to use it in one of my application, was worried about this because I will have to write clients for Unity or any other game engine, so depending on a third-party library can be quite challenging