Glossary:
Nirvana JavaScript : WebSocket Delivery Mode
An Introduction to WebSockets
WebSocket is an emerging HTML5 protocol which provides full-duplex communication over a TCP socket. The WebSocket API is currently being developed by W3C and the WebSocket Protocol standardized by IETF.
WebSocket is supported by all major browser vendors. It is currently enabled in Google Chrome (6+), Mozilla Firefox (6+), Apple Safari (5+) and Internet Explorer (HTML5 Labs only).
WebSockets serve as an effective low-latency alternative to comet based solutions such as XMLHTTPRequest LongPoll or Forever IFrame. It provides browser-based communication which does not rely on opening multiple HTTP communications, unlike the aforementioned comet based techniques.
WebSockets in Nirvana
Nirvana supports WebSocket browser-based communication through our JavaScript API. In addition to WebSockets our JavaScript API offers both LongPolling and Forever IFrame communication modes. In situations where it is possible to use WebSocket however there is significant performance gains to be had.
The client indicates that it wishes to communicate with the server using WebSocket by specifying the following configuration when starting a session:
NirvanaSession.start({
...
protocolSelection : ["websocket","streamingcomet","longpollcomet"],
webSocketPort : 9000
});
If the browser running this JavaScript code does not support WebSockets, it will seamlessly switch to an alternative delivery mode which is supported. In the example above, this would be Forever IFrame.
In some cases it is desirable to communicate in a secure manner using WebSocket secure (wss) instead of unencrypted WebSocket (ws). To do this using our JavaScript API, the following snippet is used:
NirvanaSession.start({
...
protocolSelection : ["websocket"],
webSocketPort: 9443,
secure : true
});
Sometimes unsecured WebSocket connections cannot be established because of intermediary network infrastructure such as proxies or firewalls. Some anti-virus software may also block or restrict the creation of a WebSocket on some ports. These problems can often be overcome by switching to the WebSocket Secure (wss) protocol.
WebSocket interaction with Proxy Servers
As the adoption of WebSocket becomes more widespread an increasing number of proxy vendors are supporting communication over WebSocket. There still remain cases however where WebSocket connections cannot be established because of a proxy server or firewall which blocks this connection.
The reasons for this are twofold. Some proxy servers have not been updated to handle the protocol, treating requests to establish the connection as normal HTTP traffic. WebSocket requests are also known not to conform with the HTTP 1.0 spec, causing some proxies to reject them.
Below we cover methods for configuring the Nirvana server, client and proxy which guarantee the highest likelihood of success.
WebSocket communication over a Forward Proxy
A Forward Proxy (often just referred to as a proxy) acts as an intermediary between a client and a browser. If the proxy is explicitly configured it is usually possible to establish a WebSocket connection to a server without the need for further configuration.
This generally works because in cases where a browser is configured to use an explicit proxy server it will issue an HTTP CONNECT request to the proxy when establishing the WebSocket connection. The Connect method enables the proxy to act as a tunnel between the client and server.
There are two cases where this method may not work. In some situations the proxy may be configured to restrict use of the HTTP CONNECT method. In other situations the request may travel through a proxy which is not explicitly configured (a transparent proxy). As the browser has no knowledge of the proxy, it will not issue the HTTP CONNECT request.
One approach that will likely grant connectivity in both of these situations would be to use the secure version of the protocol. As the data sent is encrypted when sent the proxy server it is unable to manipulate it in any way. In these situations it will often forward the request from the client to the server intact and a connection can be established.
An example on configuring a forward proxy which works with WebSocket is available here
WebSocket communication over a Reverse Proxy
A reverse proxy is a server which appears to clients to be an ordinary server. The client issues requests directly to this proxy. Based on a set of rules the proxy server will then forward this request to one or more origin servers which handle the request. The response is sent back through the proxy and it appears to the client that this response originated directly from the reverse proxy itself.
WebSocket communication through reverse proxy servers using the application layer (HTTP in this case) may work in some but not all scenarios. The proxy server must provide support for WebSockets (HAProxy for example, does). Furthermore the client wishing to communicate using WebSockets must use a version greater than 8 of the protocol.
WebSocket communication through a reverse proxy using clients which use a previous version of the protocol is generally not possible. This is because of a recognised flaw corrected after version 8 of the protocol. This flaw manifests itself because older versions of the protocol included 8 bytes of key data after the header during a connection upgrade request. This data was not advertised in the Content-Length header. Because of this most application layer proxies will discard this data.
Reverse proxies which support forwarding at the Transport layer (layer 4 of the OSI model) can still be used with older versions of the WebSocket protocol. As layer 4 proxies do not inspect the contents of a HTTP requests header (whereas application layer proxies do) the key data is not removed when traversing over them.
When traversing reverse proxies which forward at the transport layer both secure and non-secure communication modes are likely to work. When specifying a WebSocket port to connect to when using a reverse proxy, the client must use the port which the reverse proxy is listening to connections on. It should not attempt to connect to the port which the Nirvana realm interface is listening on.
For example, if a reverse proxy is listening for secure connections on port 443 and forwarding requests to a Nirvana nhps interface listening on port 9443 the options the client provided should be:
NirvanaSession.start({
...
protocolSelection : ["websocket"],
webSocketPort : 443, // Note that this is the reverse proxy port
secure : true
});
Examples of configured reverse proxies which work with WebSocket are available here
