RFC 6455 – Websocket


I have been exploring Websocket RFC 6455 recently and wanted to share my thoughts on this HTML5 addition to web technologies. Websocket provides an API and HTTP upgrade mechanism to take a standard HTTP request and upgrade it to a bi-directional socket connection. The standard includes a simple JavaScript API to instantiate a new socket and listen for events connect, close, message while being able to send messages programmatically.

Port 80/443 - The first barrier with any network communication is firewall traversal. Port 80(HTTP) and Port 443(HTTPS) are typically open both ways within firewalls. Although Websockets can operate on custom ports, they default operation to using port 80/443 depending on the protocol selected. The key is that HTTP has always used TCP/IP Sockets to communicate. When you make a URL GET/POST/HEAD request you make a TCP/IP socket connection to the target server and send a header. The server responds and closes the connection unless it is using HTTP1.1 which simply provides more persistant connections supporting multiple requests.

2 Way – Websockets allows the server or client to send messages at any time without requiring a request. After the initial HTTP handshake, you can send data to the server and the server can send data to the client. The key is that a request does not imply the server will respond and thus there are 2 independent channels of messages.

I tested Websocket using Play (Java) and Tornado(Python) Frameworks and found it trivial to get up and working with Websockets quickly. Both frameworks provide a simple means to defining a route to serve the Websocket handshake and provide events for events. Given the symmetry within the Websocket, both client and server are very similar in API. Here is the Websocket Class in Play and Tornado:

#Tornado Framework - Websocket Class
class EchoWebSocket( tornado.websocket.WebSocketHandler ):
  def open( self ):
    print "WebSocket opened"

  def on_message( self , message ):
    print "You said: " + message
    self.write_message( message )

  def on_close( self ):
    print "WebSocket closed"
//Play Framework - Websocket Controller
public class Application extends Controller {
  public static WebSocket<String> live() {
    return new WebSocket<String>() {
      public void onReady(final WebSocket.In<String> in, final WebSocket.Out<String> out){
        in.onMessage(new Callback<String>() {
          public void invoke(String event) {
            out.write("onmessage:" + event);
          } 
        });

        in.onClose(new Callback0() {
          public void invoke() {
            Logger.info("onclose");
          }
        });
        out.write("Connected");
      }
    }
  }
}

Compatibility – Today the Websocket API is deployed in the following browsers: IE10+, FF14+, Chrome 21+, Safari 6+, Opera 12, IOS 6+, Chrome Android 4+, and BB7+. With proper fallback to Flash Player on desktop browsers, this provides a very solid base of support.

JavaScript API – The JavaScript API is fairly simple to use. You simply create a new instance of WebSocket and pass in a ws:// or wss:// uri to the target server. Here is an sample:

socket = new WebSocket( "ws://example.com/live" );
socket.onopen = function( event ) { onOpen( event ) };
socket.onclose = function( event ) { onClose( event ) }; 
socket.onmessage = function( event ) { onMessage( event ) }; 
socket.onerror = function( event ) { onError( event ) };

There are some interesting service possibilities with Websockets allowing clients to query a services layer within a persistant socket connection. The hard part with Websockets is handling scalable server architectures where messages must traverse multiple servers between multiple clients. Although this is a very solvable problem with messaging libraries like ZeroMQ and server to server socket connections.

Try Websockets out! Here is a full Websockets server written in Tornado Framework in Python. It is a single file and should be fairly easy to run once you install the Tornado libraries into Python locally. Instructions for installation are located within the file itself.

Cheers,

Ted :)

One thought on “RFC 6455 – Websocket

  1. Roger

    Ted,
    I only just found your site & I thought I would share our websockets experiences … to let you in on a use for them that perhaps may have not been considered.
    We have developed a pretty big Sencha Touch (1.1.1) / Phonegap App (has 100 SQLite tables, about 130 different UI screens) and use WebSockets to move data to/from the tables … synchronising with our dektop software’s SQL Server database on our user’s office PCs.
    We developed our own client-side websocket handling for Androids in Java, are we’re relying on the iOS Safari websocket handling on iOS devices.
    On the office PC’s we’ve used Alchemy’s server-side Websocket system and within this service we convert JSON data to SQL insert statements and vice versa.
    All the data is transferred in JSON format.
    We had to do a fair bit of fixing & hacking, but we got there.
    We use a Port No other than 80 or 443.
    So far we have around 120 users on this, using WiFi for synchronising the data, or 3G or 4G if they have a Static IP address.

    Pretty amazing stuff. Works well.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s