Tuesday, January 5, 2010

Web Sockets: a new era for the Web

The Web Sockets API is a part of HTML 5 specification and is to the Web what TCP is to the IP protocol. It allows full-duplex, bidirectional communication between the server and the client browser - no more polling, no more busy waiting, and no more problems with keep-alive HTTP connections. Web Sockets allow to leverage Web applications to an absolutely new level, where they can finally operate like any other network software, without crippled overlays like AJAX or Comet. With Web Sockets you can push data to the client just as you would do it with XMPP.
One of the first browsers to support Web Sockets is Google Chrome. And, of course, one of the first languages natively supporting Web Sockets is Go. Here is a simple server application which sends time information to the browser in one second intervals:

package main

import (
"http"
"io"
"strconv"
"time"
"websocket"
)

func ClockServer(ws *websocket.Conn) {
ch := time.Tick(100000000)
t1 := <- ch
t := t1 / 1000000000
for {
t2 := <-ch
td := (t2 - t1) / 1000000000
if td != t {
io.WriteString(ws, strconv.Itoa64(td))
t = td
}
}
}

func main() {
http.Handle("/clock", websocket.Handler(ClockServer))
err := http.ListenAndServe(":12345", nil)
if err != nil {
panic("Error: ", err.String())
}
}

When you compile and start the server, create a web page with the following content and save it to your disk:

<html>
<head>
<title>WebSocket</title>
<script type="text/javascript">
function init() {
var tick = document.getElementById("tick");
if ("WebSocket" in window) {
var ws = new WebSocket("ws://localhost:12345/clock");
ws.onmessage = function (evt) {
tick.innerHTML = evt.data;
};
} else {
tick.innerHTML = "The browser doesn't support WebSocket.";
}
}
</script>
</head>
<body onload="init()">
<span>Seconds elapsed: </span><span id="tick">0</span>
</body>
</html>

If you open the page in Google Chrome, you will see seconds ticking. There is no AJAX, no long-polling or any other fancy stuff - the server pushes data directly to the client. If you open more Chrome instances, you will see that each of them has its own connection with the server with its own clock (however, beware opening many connections in the same window, but in different tabs - this can occasionally crash your browser).
You can also use Erlang to make use of Web Sockets technology. Joe Armstrong has recently posted an article on his blog with full source code of both Web Sockets client and server.
Have fun!

1 comment:

Peter Lubbers said...

Hi Krzysztof,
Great post and great example, too. The start of this new decade seems to definitely be the start of the new era you're talking about!
You might be interested in taking a look at Kaazing WebSocket Gateway as well--it provides emulation for all the older (read: non Chrome) browsers. It also ships with protocol libraries that are built on top of WebSocket APIs, such as the XMPP protocol you mentioned as well as libraries for Atomp, AMQP and more.