I'm thinking about how I position Adama for both Jamstack and as a reactive data-store (which could feed phoenix/elixer land). I intend to change my marketing away from the "programming language" aspect and more towards "reactive data store".
One of the issues with nodejs is that you're stuck to one process which is single threaded. IE: you're stuck to one core. Yes there are systems like clustering which relies on a master process spawning slave processes and communicating over a bridge but in my experience, its pretty janky.
You're making a great move by trying out elixir. It solves a lot of the issues I ran into working with nodejs. Immutability is standard and if you compare two maps, it automatically does a deep evaluation of all the values in each tree.
The killer feature however is liveview. Its what meteor WISHES it could be. realtime server push of html to the dom and teh ability to have the frontend trigger events on the backend in a process thats isolated to that specific user. Its a game changer.
Anyways, if you're looking for resources to learn. pragprog has a bunch of great books on elixir. Thats how I got started.
You might find an interesting (albeit more complex) entry point by interacting with Phoenix Channels from your Node.js app using the Channels Node.js client [1] and within the frontend itself.
[0]: https://hexdocs.pm/phoenix/channels.html [1]: https://www.npmjs.com/package/phoenix-channels
For a good introduction to Elixir, I loved Elixir in Action which also covers OTP.
If you want a good Phoenix resource, the book Programming Phoenix is good.
Finally, the docs in Elixir and Phoenix are great.
The new LiveView book is great if you're interested in going fully into Elixir (server/client basically). I use LiveView for my product and it's great.
You could in theory replicate the protocol in another stack but its more than that. Elixir is uniquely suited to websocket applications. Since a websocket is persistent, you need a process on your end that handles that. Elixir is excellent at creating lightweight threads for managing these connections. Out of the box, you can easily support a few thousand connections on a single server.
I know because we did it at my startup. channels powers our entire realtime sync system and its yet to be a bottleneck. It more or less works out of the box without issue. Its almost boring level reliable.
I think that the important question is "why does this protocol exist?" Most likely, you'll end up solving similar problems as to why Channels exist in the first place. So from a protocol perspective, it's nice that some problems are solved for you.