I put this together for two reasons. For some time now, I have been looking for a way to communicate with my teenage sons while they are in the midst of some online gaming experience (which seems to be most of the time these days). It had got to the point that they wouldn´t answer their phones or check their WhatsApp messages, and I would have to resort to speaking to them via Discord. Or, in the case of the younger one who is at least still in the same house, I would have to go upstairs and switch the light on and off a few times so that he would take his headphones off. This little web application allows me to send text and audio messages, so I can effectively broadcast when it is “Time for dinner!”.

The second reason for doing this was that I was looking for a simple example as a starting point for the aforementioned teenage sons to develop a simple online game, as they are both studying Computer Science. I have suggested that they program an online Cards Against Humanity game, so that we can play as a family with the eldest (who is at university). As a result, I have deliberately made the code as simple as I can, rather than making the application particularly robust, attractive or portable. I deliberately avoided using CSS or any external libraries such as JSQuery or Bootstrap. If you are running this on an iPhone, you will need at least iOS 13 and may have to enable MediaRecorder in the Safari Advanced Experimental Settings.

To use it, choose a name and a room (or press “Create room” to assign one randomly). You can then type in a message and pressing “return” will send it. Press the “Speak” button to record a voice message and press it again to send it (it will timeout after one minute). (Note that a tab will not play audio unless the user has interacted with it previously. Also, if it is not focussed the first time it receives audio, it will only play the audio once it comes into focus.)

The backend is a Node.JS HTTP server that serves up the frontend index.html as well as handles sending and receiving messages via websockets. The frontend is a static webpage that uses MediaRecorder to record the audio. To run it you first need to install the requisite packages with

npm install

from the application directory and then run the server with

node app.js

You´ll want to change the URL for the websocket to point to your Node.JS server (e.g., “ws://localhost:3001”). I’m using ProxyPass on my Apache web server to forward a node (https://deej-ai.online/chat) to a port (3001) on locahost. Getting this to work with websockets actually took me more time to figure out than the backend and frontend put together, so I am including the magic lines to include in the site configuration file here. If you do this, make sure you use the appropriate protocol: “ws://” for websockets over HTTP connecttions and “wss://” for websockets over HTTPS.

ProxyPass "/chat" "http://localhost:3001/"
ProxyPassReverse "/chat" "http://localhost:3001/"
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /chat(.*) ws://localhost:3001/$1 [P,L]

PS: I have updated it to be deployable out of the box on Heroku.

You can find the repo here.