This article describes how to inspect and load-balance WebSockets traffic using Stingray Traffic Manager, and when necessary, how to manage WebSockets and HTTP traffic that is received on the same IP address and port.

Overview

WebSockets is an emerging protocol that is used by many web developers to provide responsive and interactive applications. It's commonly used for talk and email applications, real-time games, and stock market and other monitoring applications.

By design, WebSockets is intended to resemble HTTP. It is transported over tcp/80, and the initial handshake resembles an HTTP transaction, but the underlying protocol is a simple bidirectional TCP connection.

Paste the libWebSockets.txt library to your Rules catalog and reference it from your TrafficScript rule as follows:

import libWebSockets.rts as ws;

You can then use the ws.* functions to inspect and modify WebSockets handshakes. Common operations include fixing up host headers and URLs in the request, and selecting the target servers (the 'pool') based on the attributes of the request.

Ensure that the rules associated with WebSockets virtual server are configured to run at the Request stage, and to run 'Once', not 'Every'. The rule should just be triggered to read and process the initial client handshake, and does not need to run against subsequent messages in the websocket connection:

Code to handle the WebSocket handshake should be configured as a Request Rule, with 'Run Once'

SSL-encrypted WebSockets

Stingray can SSL-decrypt TCP connections, and this operates fully with the SSL-encrypted wss:// protocol:

Enable SSL decryption on the virtual server, using a suitable certificate

Note that when testing this capability, we found that Chrome refused to connect to WebSocket services with untrusted or invalid certificates, and did not issue a warning or prompt to trust the certificate. Other web browsers may operate similarly. In Chrome's case, it was necessary to access the virtual server directly (https://), save the certificate and then import it into the certificate store.

Handling HTTP and WebSockets traffic

HTTP traffic should be handled by an HTTP-type virtual server rather than a Generic Streaming one. HTTP virtual servers can employ HTTP optimizations (keepalive handling, HTTP upgrades, Compression, Caching, HTTP Session Persistence) and can access the http.* TrafficScript functions in their rules.

If possible, you should run two public-facing virtual servers, listening on two separate IP addresses. For example, HTTP traffic should be directed to www.site.com (which resolves to the public IP for the HTTP virtual server) and WebSockets traffic should be directed to ws.site.com (resolving to the other public IP):

Configure two virtual servers, each listening on the appropriate IP address

Sometimes, this is not possible – the WebSockets code is hardwired to the main www domain, or it's not possible to obtain a second public IP address. In that case, all traffic can be directed to the WebSockets virtual server and then HTTP traffic can be demultiplexed and forwarded internally to an HTTP virtual server:

Listen on a single IP address, and split off the HTTP traffic to a second HTTP virtual server

The following TrafficScript code, attached to the 'WS Virtual Server', will detect if the request is an HTTP request (rather than a WebSockets one) and hand the request off internally to an HTTP virtual server by way of a special 'Loopback Pool':

Notes: Testing WebSockets

The implementation described in this article was developed using the following browser-based client, load-balancing traffic to public 'echo' servers (ws://echo.websocket.org/, wss://echo.websocket.org, ws://ajf.me:8080/).

It''s definitely a possibility... we're waiting to see what the feedback on this approach is. I appreciate this dual-virtual-server design is a little more complex than we would like, so if it's popular, there's a good case to add this capability to a HTTP virtual server.

Consider this article to be a tentative prototype for a future product feature, and please let us know how well it works for you.

I had to modify your lib websocket, because some clients didn't wait for the confirmation of the socket upgrade, and were sending data directly on the first request. (i don't say this behavior is clean, but it happens...)

On the updateRequest function, request's data are replaced only with the headers and without the eventual data received after the headers on the same request.

Here our simple modification :

--- libWebsocket.txt 2013-06-19 12:23:24.000000000 +0200

+++ libWebsocketSky.txt 2013-06-19 12:27:50.000000000 +0200

@@ -113,6 +113,9 @@

$t = "\n";

if( endsWith( $first, "\r\n" ) ) $t = "\r\n";

connection.data.set( "ws-TERMINATOR", $t );

+

+ # Split the request to only get headers on the 1st request

+ request.endsWith($t . $t);

# Headers are prefixed by a terminator to make searches easier, and

# end with the double-terminator

Has Andrew, we are really expecting integration of websockets on HTTP virtual servers.

Some, but not all of the content in this site provided, reviewed, approved or endorsed by Brocade and is provided solely as a convenience of our customers. All postings and use of the content on this site are subject to the BROCADE EXTRANET TERMS AND CONDITIONS OF USE of the site. BROCADE ASSUMES NO LIABIITY WHATSOEVER, MAKES NO REPRESENTATION AND DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO THE CONTENT PROVIDED HEREIN, INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, CORRECTNESS, APPROPRIATENESS OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY INTELLECTUAL PROPERTY RIGHTS IS GRANTED EXPECT AS PROVIDED IN BROCADE’S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS, THIRD PARTIES USE THIS CONTENT AT THEIR OWN RISK. Content on this site may contain or be subject to specific guidelines or limitation on use. Third parties using this content agree to abide by any limitation or guidelines and to comply with the BROCADE EXTRANET TERMS AND CONDITIONS OF USE of this site. Brocade may make changes to this content, to specifications, or product design or descriptions at any time, or may remove content at its sole discretion without notice.