When web sockets won't work (Web socket handshaking updates)
13 Aug 2010This post serves as a update to my previous post: Getting started with Node.js and Web Sockets on Ubuntu 10.04 In which I stated various problems I had encountered. In this post I will explain why most of them occurred. In this post I refer mostly to the server side handshake, the client side processing is a 45 step process which looks pretty nightmarish to me!
After more in depth research I’ve discovered the cause of many the examples I tried in my previous post. On the 6th June 2010 the handshake for the web sockets protocol was changed and broke backwards compatibility with earlier implementations. This means that now you have to ensure the browser version you are using supports the same handshake as server. I suspect due to me not knowing this that many examples failled to work as I sporadically switched between builds of chromium and node.js - to guarantee support you need to use the latest version of Node.js and Chromium/Chrome 6.0.414.0 or above.
I also attempted to use the Arduino websockets library without success which I now find uses an old protocol, it is my intention to attempt to remedy this when I have time.
The new server > client handshake was summerised by Makoto in 7 steps:
- Extract numbers at Key1(eg: 4 @1 46546xW%0l 1 5) and concatenate them
- Count number of spaces at Key1
- Devide #1 by #2
- Change the format of #3 into "big-endian 32 bit integer"
- Repeat #1 by #4 for Key2(eg: 12998 5 Y3 1 .P00)
- Concatenate #4, #5, and the body(eg:
^n:ds[4U
) of the request - Digest the result in MD5 format
The new server handshake is not complex but is a bit heavyweight for microcontrollers. A nice example of implementation of this in PHP can be found here:
http://webreflection.blogspot.com/2010/06/websocket-handshake-76-simplified.html
and the full, latest details of the handshake can be found here:
http://www.whatwg.org/specs/web-socket-protocol/ (currently on page 6)
I have mixed opinions on this update, on one hand it means the web sockets protocol is no longer strictly initiated by an http GET request as it has extra data in the header, on the other hand it seems sensible to incorporate some kind of validation mechanism for clients. What it may mean for Arduino implementations of the protocol I don’t yet know, it is my gut feeling that the server part may be too complex to easily implement. It is less likely for an Arduino client to be required but I would not like to attempt implementing the 45 step handshake required for a client on an Arduino.
Rather than using Node.js I have moved to using pywebsocket for my experiments as it seems to be used by the Google team working on web sockets and thus is very quickly updated in line with the newest developments. So far I have tried using both Chromium and Firefox 4 daily build as clients.