Peter's website random notes

Creating websocket connections via 9front's webfs

With the following patch (note: work in progress, contains bugs), 9front's webfs can be used to create websocket connections. The patch is available here.

The idea

Creating a websocket connection is done just like creating a http request is, except the url must use scheme wss:// or ws://, and the body file must be opened read-write to allow both sending and receiving.

The very first message to be read from body is always "websocket ready", meaning the connection has been established. After that the actual communication begins.

Webfs itself takes care of the control messages, so only the data messages gets delivered to the user, in a textual format that is easy to parse. Each message read and writen to body consists of a 22 byte header in the following format

b nnnnnnnnnnnnnnnnnnnn


t nnnnnnnnnnnnnnnnnnnn

for binary and text messages respectively. The 20 last bytes are a 0-padded ascii number in base 10, telling the size of the message body, which follows directly after the header.

Example program

To demonstrate, the following rc script connects to wss:// which is a service that echos everything back to the user.


rfork en


fn sendtextmsg{
	awk 'BEGIN{printf "t %0.20d%s", length(ARGV[1]), ARGV[1]}' $1 >[1=0]

fn readheader{
	header=`{read -c 22}
	length=`{echo $header(2) p | dc}
	echo $header(1) $length

fn handlemsg{
	echo Handling message:
	echo '	TYPE  :' $1
	echo '	LENGTH:' $2
	echo '	BODY  :' $3

<>/mnt/web/clone {
	d=/mnt/web/^`{sed 1q}

	echo url wss:// >[1=0]

	<>$d/body {
		read -n 1 # Read the ready message

		sendtextmsg 'First message sent'
			echo Header: $header
			body=`''{read -c $header(2)}
			handlemsg $header(1) $header(2) $body
			sleep 2
			sendtextmsg 'Echo test'


Yes. The code doesn't really handle errors or connection shutdowns yet. Also, I need to add proper cleanup code around in different places.