If you're like me, then you must have gone nuts on hearing about WebSockets for the first time. We now have a totally independent protocol that will not terminate connection after a request-response cycle, which means all hacks to keep a persistent connection from the browser (long polling, I'm looking at you) would now be part of the history. Welcome to the world of WebSockets.
Let's start with the Wikipedian and Mozillian definition of WebSockets, to get some initial traction.
Wikipedia says that..
WebSocket is a protocol providing full-duplex communication channels over a single TCP connection. The WebSocket protocol was standardized by the IETF as RFC 6455 in 2011, and the WebSocket API in Web IDL is being standardized by the W3C.
Mozilla Developer Network says that..
WebSockets is an advanced technology that makes it possible to open an interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply.
To begin with, let us all make sure we have websocket support by clicking . Assuming you do, let's begin. Web browsers provide us with the
WebSocket class. To create a websocket, we simply need to
let ws = new WebSocket('ws://server.com/endpoint');This gives us a websocket object which supports methods like send() and close() and event listeners like onmessage and onerror.
Creating a nodejs instance running a websocket server is easy with modules. I did try to do it natively, but it went too tedious. Finally I settled for
ws module from npm. The server side code looks trival.
On the browser, things are even simpler.
Once we call the constructor, an HTTP GET request is generated to initiate the transaction. You'll find that these headers are sent by your browser.
GET / HTTP/1.1 Host: nagekar-ws.herokuapp.com Connection:Upgrade Pragma:no-cache Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits Sec-WebSocket-Key:ut0NjBQxxBnmtUStHfMUDw== Sec-WebSocket-Version:13 Upgrade:websocket User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.108 Safari/537.36
The ones to notice are the URL, which begins with ws:// protocol. Cross domain requests are allowed. This initial step requires the use of HTTP(S) or web, hence the name 'web' sockets. The 'Connection:Upgrade' and 'Upgrade:websocket' and what requests the server to change this connection to a socket one. The Sec-WebSocket-Key header is what client sends to the server. The server crafts another key with this and returns it back in the response header. A response header looks like this.
HTTP/1.1 101 Switching Protocols Connection:Upgrade Sec-Websocket-Accept:7CAJHdL7QMG4ceqd0M1O8SDbM2Q= Sec-Websocket-Extensions:permessage-deflate Upgrade:websocket Via:1.1 vegur
On receiving the Sec-Websocket-Accept header, the handshake is completed, and now the client and server are connected via persistent sockets, ready to perform both way message delivery.
Click 'Connect' button to initiate WebSocket handshake. The server will respond with a timestamp every 2500 milliseconds. Also, the server will echo back everything to send at it. The close button will call the WebSocket.close() method which will terminate the connection.
Pretty interesting, isn't it. Things get even more interesting when you use a readymade library built on top of WebSockets, such as Socket.io. It supports all browsers (through fallback to XHR/polling), has better looking APIs, is easy to use and allows you to broadcast without having to worry much about raw connections. If you're going to use these WebSockets in production, there's no reason not to use Socket.io. Using native websockets is not recommended if you're planning to support some legacy browsers. Even Mozilla terms it as an 'experimental technology'. Check out the compatibility table for more information.
I hope this post was informative. I did learn a lot while researching on this topic, and I'm glad I did. As always, thank you for reading. Please drop a comment in case of feedback or correction.