Home / Web Gateway Configuration Guide / Web Gateway Operation and Configuration / Using WebSockets (RFC 6455)

Web Gateway Configuration Guide
Using WebSockets (RFC 6455)
Previous section           Next section
InterSystems: The power behind what matters   

Using WebSockets (RFC 6455)
The web has been built around the request/response paradigm: the client sends a request to the server and the server reacts by sending a response to the client. This paradigm, and HTTP itself, does not allow for an inverted form of this communication protocol whereby a server initiates a request/response cycle with the client. A number of technologies have been developed to create an illusion that a server can initiate a dialogue with a client. These technologies are generally known as push-based or comet-based technologies and all suffer from problems that make them unsuitable for general deployment over web infrastructure. The three main techniques in current use are described below.
Short Polling
With this technique a client regularly sends HTTP requests to detect changes in server state and the server is programmed to responds immediately. An empty response signifies no change.
Long Polling
With this technique a client sends a HTTP request but the server only responds when the client needs to be notified of a change. The client typically sends another “Long Poll” request as soon as the server sends a response message.
HTTP Streaming
This technique takes advantage of the HTTP protocol’s ability to maintain persistent (or ‘KeepAlive’) connections between the client and server. The client sends an HTTP request which is permanently kept open with the server only responding when the client needs to be notified of a change. The server does not terminate the connection after dispatching a response message and the client waits for the next message from the server (or sends a message of its own to the server).
WebSockets Protocol
The WebSockets protocol (RFC 6455) addresses the fundamental requirement of allowing servers to proactively push messages to clients by providing a full-duplex message-oriented communications channel between a client and its server. The protocol is designed to operate, and hence be secured, over the standard TCP channel already established between the client and server. In other words, the channel already used to support the HTTP protocol between a web browser and web server.
The WebSockets protocol and its API are standardized by the W3C and the client part is included with HTML 5.
Intermediaries (such as proxies and firewalls) are expected to be aware of (and expected to support) the WebSockets protocol.
Browser Support
There have been several iterations in creating the final standard for the WebSockets protocol, each with varying degrees of browser support. The history is summarized below.
The final highlighted section is the most significant for the purpose of developing portable web applications.
Server Support
The server-oriented JavaScript-based Node.js technology arguably offers the most sophisticated, and currently most mature, implementation of the WebSockets protocol. And for this reason, WebSockets have been closely associated with Node.js up until the time of writing (March 2013). However, other web server technologies are quickly catching up and the latest versions of all major web servers now offer WebSockets support as shown below.
The highlighted section is the most significant for the purpose of developing portable web applications with CSP.
Protocol in Detail
Creating a WebSocket involves an ordered exchange of messages between the client and the server. First, the WebSocket handshake must take place. The handshake is based on, and resembles, an HTTP message exchange so that it can pass without problem through existing HTTP infrastructure.
The web server recognizes the conventional HTTP header structure in the handshake request message and sends a similarly constructed response message to the client indicating that it supports the WebSocket protocol - assuming it is able to. If both parties agree then the channel is switched from HTTP (http://) to the WebSockets protocol (ws://).
Typical WebSocket Handshake Message from Client
GET /csp/user/MyApp.MyWebSocketServer.cls HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://localhost
Typical WebSocket Handshake Message from Server
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
Note how the client handshake message requests that the protocol be upgraded from HTTP to WebSocket. Note also the exchange of unique keys between the client (Sec-WebSocket-Key) and server (Sec-WebSocket-Accept).
WebSockets Client Code (JavaScript)
In the browser environment the client side of the WebSocket protocol is implemented in JavaScript code. Standard text books describe the usage model in detail. This document will briefly describe the basics.
Create a WebSocket
The first parameter represents the URL identifying the server end of the WebSocket application. The second parameter is optional, and if present, specifies the sub-protocol that the server must support for the WebSocket connection to be successful.
var ws = new WebSocket(url, [protocol]);
ws = new WebSocket(((window.location.protocol == "https:")
     ? "wss:" : "ws:") \
     + "//" +
     + /csp/user/MyApp.MyWebSocketServer.cls);
Note how the protocol is defined as either ws or wss depending on whether or not the underlying transport is secured using SSL/TLS.
The read-only attribute ws.readyState defines the state of the connection. It can take one of the following values:
The read-only attribute ws.bufferedAmount defines the number of bytes of UTF-8 text that have been queued using the send() method.
WebSocket Events
The following events are available.
Data received in
WebSocket Methods
The following methods are available.
WebSockets Server Code
The base InterSystems IRIS class for implementing WebSocket Servers is%CSP.WebSocket
When the client requests a WebSocket connection, the initial HTTP request (the initial handshake message) instructs the CSP engine to initialize the application's WebSocket server. The WebSocket server is the class named in the requesting URL. For example, if your WebSocket server is called MyApp.MyWebSocketServer and is designed to operate in the USER namespace then the URL used to request the WebSocket connection is:
WebSocket Events
The implementation of the WebSocket server is derived from the base %CSP.WebSocket class. There are three key methods to implement as responses to the following events. Note that the web session is unlocked before calling any of these methods.
OnPreServer (optional)
Use this method to invoke code that should be executed before the WebSocket server is established. Changes to the SharedConnection property must be made here.
Server (Mandatory)
The WebSocket server. This is the server-side implementation of the WebSocket application. Messages can be exchanged with the client using the Read() and Write() methods. Use the EndServer() method to gracefully close the WebSocket from the server end.
OnPostServer (optional)
Use this method to invoke code that should be executed after the WebSocket server has closed.
WebSocket Methods
The following methods are provided
Method Read(ByRef len As %Integer = 32656,
     ByRef sc As %Status,
     timeout As %Integer = 86400) As %String
This method reads up to len characters from the client. If the call is successful the status (sc) is returned as $$$OK, otherwise one of the following error codes is returned:
Method Write(data As %String) As %Status
This method writes data to the client.
Method EndServer() As %Status
This method gracefully ends the WebSocket server by closing the connection with the client.
Method OpenServer(WebSocketID As %String = "") As %Status
This method opens an existing WebSocket Server. Only a WebSocket operating asynchronously (SharedConnection=1) can be accessed using this method.
WebSocket Properties
The following properties are provided:
SharedConnection (default: 0)
This property determines whether the communication between the client and WebSocket server should be over a dedicated Web Gateway connection or asynchronously over a pool of shared connections. This property must be set in the OnPreServer() method and may be set as follows:
This property represents the unique identity of the WebSocket.
This property represents the hosting CSP Session ID against which the WebSocket was created.
This property instructs the Web Gateway to bypass functionality that would otherwise interpret the transmitted data stream as UTF-8 encoded text and set the appropriate binary data fields in the WebSocket frame header.
This should be set to 1 before writing a stream of binary data to the client. For example:
Set ..BinaryData = 1
WebSockets Server Example
The following simple WebSocket server class accepts an incoming connection from a client and simply echo back data received.
The timeout is set to 10 seconds and each time the Read() method times-out a message is written the client. This illustrates one of the key concepts underpinning WebSockets: initiating a message exchange with the client from the server.
Finally, the WebSocket closes gracefully if the client (i.e. user) sends the string exit.
Method OnPreServer() As %Status
   Quit $$$OK

Method Server() As %Status
   Set timeout=10
   For  {
      Set len=32656
      Set data=..Read(.len, .status, timeout)
      If $$$ISERR(status) {
If $$$GETERRORCODE(status) = $$$CSPWebSocketClosed {
         If $$$GETERRORCODE(status) = $$$CSPWebSocketTimeout {
               Set status=..Write(“Server timed-out at “_$Horolog)
      else {
         If data="exit" Quit
         Set status=..Write(data)
   Set status=..EndServer()
   Quit $$$OK

Method OnPostServer() As %Status
   Quit $$$OK

WebSockets Server Asynchronous Operation
The example given in the previous section illustrates a WebSocket server operating synchronously with the client over a dedicated InterSystems IRIS connection. When such a connection is established it is labeled as WebSocket in the status column of the Gateways Systems Status form. With this mode, the WebSocket is operating within the security context of the hosting web session and all properties associated with that session can be easily accessed.
With the asynchronous mode of operation (SharedConnection=1), the hosting connection is released as soon as the WebSocket Object is created and subsequent dialogue with the client is over the pool of shared connections: messages from the client arrive via the conventional pool of Web Gateway connections to InterSystems IRIS and messages to the client are dispatched over the pool of Server connections that have been established between the Web Gateway and InterSystems IRIS.
In asynchronous mode, the WebSocket Server becomes detached from the main web session: the SessionId property holds the value of the hosting Session ID but an instance of the session object is not automatically created.
The example given previously can be run asynchronously simply by setting the SharedConnection property in the OnPreServer() method. However, it is not necessary to have an InterSystems IRIS process permanently associated with the WebSocket. The Server() method can exit (and the hosting process halt) without closing the WebSocket. Provided the WebSocketID has been retained, the WebSocket can be subsequently opened in a different InterSystems IRIS process and communication with the client resumed.
Class MyApp.MyWebSocketServer Extends %CSP.WebSocket

Method OnPreServer() As %Status
   Set ..SharedConnection = 1
   Quit $$$OK

Method Server() As %Status
   Quit $$$OK

Method OnPostServer() As %Status
   Quit $$$OK

Note that the WebSocketID is retained for subsequent use in the OnPreServer() method. Note also, the setting of the SharedConnection property in the OnPreServer() method and that the Server() method simply exits.
Subsequently retrieving the WebSocketID:
Re-establishing a link with the client:
Set ws=##class(%CSP.WebSocketTest).%New()
Set %status = ws.OpenServer(WebSocketID)
Reading from and writing to the client:
Set %status=ws.Write(message)
Set data=ws.Read(.len, .%status, timeout)
Finally, closing the WebSocket from the server side:
Set %status=ws.EndServer()

Previous section           Next section
View this book as PDF   |  Download all PDFs
Copyright © 1997-2019 InterSystems Corporation, Cambridge, MA
Content Date/Time: 2019-04-10 14:45:56