PHP WebSocket Server – The Handshake

WebSockets are the new cool boys in town, but the specs are in a very early state and so it’s hard to keep up to date with the different browser implementations …

Current stable browser-versions, like Chrome 5, only supports the old specification (aka -75), Firefox 3.6 don’t know the WebSockets object at all. The new Beta-/Dev-versions of Firefox and Chrome now supports the new spec-version -76. There is one major change in the new draft, the handshake is much more complicated now …

The Browsers now sends some security strings and the WebSocket server have to implement a handling for this new headers (Sec-WebSocket-Key1 and Sec-WebSocket-Key2), and must return a security-hash:

To prove that the handshake was received, the server has to take three pieces of information and combine them to form a response. The first two pieces of information come from the |Sec-WebSocket-Key1| and |Sec-WebSocket-Key2| fields in the client handshake … The third piece of information is given after the fields, in the last eight bytes of the handshake, expressed here as they would be seen if interpreted as ASCII

Here is the PHP Method for handling the new security hashes:

    private function getHandshakeSecurityKey($key1, $key2, $code) {
        return md5(
            pack('N', $this->handleSecurityKey($key1)).
            pack('N', $this->handleSecurityKey($key2)).
            $code,
            true
        );
    }
 
    private function handleSecurityKey($key) {
    	preg_match_all('/[0-9]/', $key, $number);
    	preg_match_all('/ /', $key, $space);
    	if ($number && $space) {
    		return implode('', $number[0]) / count($space[0]);
    	}
    	return '';
    }

For the full source code of a PHP5 WebSockets server view the source of my WebSocketServer.php Class. If you want to see it in action, try my WebSockets example with Firefox 4 Beta or Chrome/Safari 5.

The original code comes from Web Reflection Blog by Andrea Giammarchi.