January 23, 2011

Socket.IO Framing Protocol

Socket.IO is a great library and framework that doesn't seem to have a good description of the protocol available. In interest of helping others when they google "socket.io framing protocol", this post was born.

The description of the framing protocol used by Socket.IO below is taken from ajaxorg's Socket.IO-node fork on github. I have made some changes with regards to the annotations, specifically that they must be terminated by with newline. This description is current for v0.6+.

Socket.IO Framing Protocol

Socket.IO 's framing protocol is on top of the underlying transport. Messages have the following format:
(message type)":"(content length)":"(data)","
Where message type is one of:

  • 0 for forced disconnect - no data is sent, always sent as 0:0:,
  • 1 for messages - see below
  • 2 for heartbeats - data is an integer, e.g. 2:1:0, 
  • 3 for session ID handshake - data is a session ID, e.g. 3:3:253,


Messages

If you were familiar with the Socket.IO protocol you will notice there appears to be no way now to specify a message contains JSON data as the new protocol has no counter part to the JSON Frame indicator ~j~. Fear not - the new Socket.IO protocol provides a means for this and many other possible extensions via annotations which maybe attachd to messages in a manner reminiscent of HTTP headers. 

A Socket.IO message now has the following format:
[key[:value]["\n"key[:value]]["\n"key[:value]..."\n"]":"[message]
In words: annotations are key-value pairs where the value may be omitted. Individual annotations are delimited by newlines, and annotations are separated from the message by another newline.

From examining the Socket.IO source, if no annotation is present then there should be no newline, but the colon is still required.

A JSON message is sent with a single annotation with key of j and no value. Below is an example taken from a debugging session:
1:128:j
:{"method":"create_user","params":[{"password":"jhhgffufuhgv","email":"h@h.com"}],"id":"83BCA0A8-7F9D-428A-A546-2EFCBDC20AB3"},
Note there is a newline after the j. The official Socket.IO client uses an additional annotation: r for realm. e.g.
1:18:r:chat
:Hello world,
Note the newline after chat.

Cheers,
Steve