WebSockets in Opera

Introduction

Opera has just released a public build with support for WebSockets. WebSockets will be supported in the final release of Opera 10.70. WebSockets provide a way to communicate between script in a Web page and the server in full-duplex mode with low latency.

Before people have tried to fake bidirectional communication using XMLHttpRequest, but this is slow since it needs to set up a new TCP connection for each message. WebSockets sets up one TCP connection and confirms that the server can speak WebSocket by doing a special handshake, after which the server and the client can send text messages over the connection at will, resulting in faster communication.

This enables applications and games that have multiple users interacting real-time (such as Quake) to run natively in the browser without plugins, with good performance.

WebSocket versions

Opera supports version -00 of the protocol (aka -76). This is the same as Chrome 6, Safari 5.0.2 and Firefox 4 beta. Older versions of Chrome and Safari supported an older version of the protocol which used a different handshake (version -75). The current version of the protocol (-02) has different framing, but the handshake is the same as in -00/-76. There has been discussion about changing the handshake, too, possibly to always use TLS with Next Protocol Negotiation. There have also been discussions about supporting multiplexing, chunking, compression, and sending binary data. This means that the protocol is likely to change in incompatible ways in the future. However, the WebSocket API is unlikely to change.

How to use WebSockets

To connect to a WebSocket server, you use the WebSocket constructor like so:

var ws = new WebSocket('ws://example.org:12345/demo');

You can also request a specific subprotocol with a second parameter:

var ws = new WebSocket('ws://example.org:12345/demo', 'my-chat-protocol');

You can try to connect to any host and any port (except blocked ports), although the server needs to support WebSockets and expect a connection from the page that opens the connection for it to be established. The meaning of the subprotocol is server-specific.

If the connection is established, the WebSocket object receives an 'open' event, at which point you can start to send and receive messages. You send a message using the send() method, and you handle incoming messages with an onmessage event listener:

ws.onopen = function(e) {
  // the connection is now established
  // let's send a message
  this.send('Hello!');
}
ws.onmessage = function(e) {
  // got a message from the server
  alert(e.data);
}

If the server refuses the connection, or if the connection closes for some reason, the WebSocket object gets a 'close' event.

ws.onclose = function(e) {
  alert('WebSocket closed :-(');
}

You can close the connection with the close() method.

ws.close();

If the server sends frames that the browser doesn't understand (maybe because the server just supports a newer version of the protocol), then you get 'error' events. If you get 'error' events and no 'message' events, you may want to close the connection and fall back to using something else.

If you want to check if the browser supports WebSockets, just do:

if ('WebSocket' in window) {
  // WebSockets supported
} else {
  // WebSockets not supported
}

Opera's contributions

When implementing WebSockets in Opera, we also developed a testsuite that covers both the protocol and the API, which tries to test all aspects of the specifications, including error handling and weird edge cases. With WebSockets we were pedantic about getting everything right, which also meant that we found a lot of bugs and inconsistencies in the specifications. The good thing is that we sent that feedback to the working group so the specifications could be fixed, and everyone is better off as a result.

The WebSocket specifications were very easy to test and implement. Having the requirements written as detailed algorithms makes it very easy to make sure that you get everything correct, and that leads to better interoperability between implementations, which is the whole point of having specifications.

You can check if your browser supports WebSockets and how well it supports WebSockets with Opera's WebSockets testsuite. You will need to install the testsuite to use it.

Conclusion

WebSockets is a promising technology that enables applications and games on the Web to support real-time multiuser communication with good performance. The API is really simple and is unlikely to change. However, the protocol is not stable yet. Happy WebSocketing! :up: