WebSocket - HTML5

Published Mar 22, 2015

The content here is under the Attribution 4.0 International (CC BY 4.0) license

HTML5 brings a lot of new features came to help developers to create amazing apps and amazing user experience, one of these features is called web socket which provides new powers under the HTTP protocol.

Web socket resolves the lack of HTTP when we need updating our clients with real time data and also server events regardless of a request.

The client side

First of all let’s have a look in the javascript code the easiest step to get web sockets working.

var mySocket = new WebSocket('ws://myserver');

mySocket.onopen = function() {};

mySocket.onclose = function() {};

mySocket.send = function() {};

mySocket.onerror = function() {};

mySocket.onmessage = function() {};

With the snippet above we already have a code working but also we can specify which protocol we want to use through or connection.

var mySocket = new WebSocket('ws://myserver', ['myProtocol']);

mySocket.onopen = function() {};

mySocket.onclose = function() {};

mySocket.send = function() {};

mySocket.onerror = function() {};

mySocket.onmessage = function() {};

Handshake

Now that we have the client already is time to concentrate in a key part of the process, the handshake. I would like to recommend if you don’t know what is and why we must do that please see this wikipedia article and this from websocket.org.

To perform a handshake we will need the client header and some hash stuff to return those combined to upgrade our header. The key header that we are looking for is the Sec-WebSocket-Key. So let’s to our example!

GET ws://echo.websocket.org/?encoding=text HTTP/1.1
Origin: http://websocket.org
Cookie: __utma=99as
Connection: Upgrade
Host: echo.websocket.org
Sec-WebSocket-Key: uRovscZjNol/umbTt5uKmw==
Upgrade: websocket
Sec-WebSocket-Version: 13

Our header value is uRovscZjNol/umbTt5uKmw== with that we will do the following steps on our server:

  • Append to the uRovscZjNol/umbTt5uKmw== the value 258EAFA5-E914-47DA-95CA-C5AB0DC85B11
  • Create a SHA1 hash with the string
  • Apply the base64 enconding to the result of the SHA 1 encode

The above steps translated to PHP code will be something like the example below

<?php
$hds; //headers grabbed from the client header

if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$hds,$matchs)){ 
  $key = $matchs[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; 
  $key = base64_encode(sha1($key, true)); 
  $headers = "HTTP/1.1 101 Switching Protocols\r\n". 
             "Upgrade: websocket\r\n". 
             "Connection: Upgrade\r\n". 
             "Sec-WebSocket-Accept: " . $key . "\r\n\r\n";
}

To deeper information go ahead and see the RFC 6455 documentation.

Wrapping everything up!

As you saw on this post to create a websocket server from scratch is a tough task, roughly we have a couple of projects that do all the hard work for us.

The most common in the PHP world is Ratchet, the documentation is awesome and the repository on github is updated frequently I do recommend Ratchet.

Edit: Mar 28, 2015