One of the big strengths of Phoenix is Channels. Channels seem to have been a key motivation for Elm’s recent 0.17 release, which introduced a new WebSocket library (that takes advantage of Elm’s new effects handlers). I had a go at trying to wire it up a simple chat app. There are many posts about Channels already so the focus here will be on Elm.
My aim was to emulate the sockets.js library that ships with Phoenix - in practise I have not got very far, but I do have working communications and a ‘library’ that factors out the Channels specific code so I thought it was time to share progress! The code is available on Github, and it includes some traditional ports based code so you can see what sort of communications the Phoenix socets.js library is generating.
Modeling a Socket Channel
Keeping things simple we’ll just store the socket’s Url and the socket’s connection state (we won’t be using the ref
yet).
Phoenix expects messages with a particular format and those that we send will need the fields in SendMsg
. Responses are similar, but not identical, in structure.
Joining a Channel
First things first: let’s join an open channel. The Phoenix docs lead you to create a “rooms:lobby” channel so we will use that. Our Channels ‘library’ has a Join Msg that uses Elm’s WebSocket library to connect. Here’s the code:
Listening to the socket
So our join message has been sent, but how we do get a response. This is where the new Subscriptions come in. WebSocket has a listen function which we need to wire up in Main.elm.
We listen on the socket Url and wrap the raw, incoming communication with app-specific Messages. One way or another we need to pass the string wrapped as Raw
to our update function to decode and establish whether our request to join has been confirmed:
Using our connection
Sending a chat message is similar to joining a channel:
Listening to others
Finally we want to hear what others have to say. Above we routed incoming socket messages to WWS.SocketMessage
, and this picks out packets with a “new_msg” tag:
Anything else (e.g. include a join confirmation) is passed on to the ‘library’ code.
This is of course just the beginning, but shows some of the latest additions to Elm working nicely with Phoenix’s core strength.