helicon
Data Serialization in Phoenix Channels
Hey!
Someone knows how to properly serialize data in channels? Can someone advise some serialization tools in the channels?
Most Liked
jmarca
Sorry for resurrecting an old thread, but I’m doing this in place of opening an issue on GitHub.
Are the requirements for how to write a client for Phoenix sockets written down anywhere. I also saw another (even older) post on this forum here Specification of the protocol used by Phoenix channels - #10 by LostKobrakai.
My problem is that reading the docs here Phoenix.Socket.Message — Phoenix v1.8.8, it says:
The message format requires the following keys:
:topic - The string topic or topic:subtopic pair namespace, for example "messages", "messages:123" :event- The string event name, for example "phx_join" :payload - The message payload :ref - The unique string ref :join_ref - The unique string ref when joining
So reading that, it seems like a proper message should be a hash (JSON object) with keys. But this isn’t the case. As noted above, the serializers and the official javascript client both create an array, in a particular order:
let payload = [
msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload
]
return callback(JSON.stringify(payload))
I came across this issue because I’m using Clojurescript on the client, and was having an impossible time trying to connect re-graph (a graphql client for the re-frame) to Phoenix/Absinthe subscriptions. Apparently the Lacinia server does something completely different, but it took me ages to drill down in the code enough to figure out that I need to send a JSON array, not a JSON object, and then to find exactly the order of the elements. I was so frustrated that I almost considered switching to a Clojure-based backend (but my Java error message PTSD pushed me to try harder to debug this!).
Given that there is no documentation of what is expected to communicate over this channel, I also don’t know the rules behind “ref” and “join_ref”. Can I just make up integers? Should “ref” increment with every new message sent over the channel? It certainly seems from the developer tools console that the Phoenix live code reloading heartbeat increments ref every time. The first message is
["3","3","phoenix:live_reload","phx_join",{}]
and then subsequent messages are:
[null,"4","phoenix","heartbeat",{}]
[null,"5","phoenix","heartbeat",{}]
...
Thanks in advance for pointers of what to read. I’m also willing to write a draft doc, something that could be linked in here: https://github.com/phoenixframework/phoenix/blob/master/guides/realtime/channels.md#client-libraries
LostKobrakai
There are a few things to unpack: %Phoenix.Socket.Message{} is the datatype used for messages within elixir. What’s send over the wire it actually fully up to the serializer used, while the question of “what is the wire” is solved by the channel transport.
Phoenix actually comes with two serializers: V1 uses json objects, while V2 uses arrays to save bytes (no keys); as well as two transports: long poll and websockets.
There’s already documentation about it here:
chrismccord
This is your only option if you don’t want to integrate with the existing phoenix.js and/or absinthe socket js libraries.
Unfortunately it’s all or nothing as Phoenix channels is more than just a pipe on top of web sockets. There’s multiplexing, heartbeats, topics, request/response acknowledgements, etc. The reality is you need a full phoenix channels client to interact with Absinthe subscriptions. I don’t know what clojurescript’s js interop story is like but it seems like the path of least resistance would be to leverage the existing js libs. Of course it would be great to have a first class cljs channels client so if that’s the way you’d like to get then great! ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #javascript
- #code-sync
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








