Skip to content

WebSockets

WebSockets is a technology providing interactive communication between a server and client. It is an IETF standard defined by RFC 6455.

Normal HTTP connections follow a request/response paradigm and do not easily support asynchronous communications or unsolicited data pushed from the server to the client. WebSockets solves this by supporting bidirectional, full-duplex communications over persistent TCP/IP connections. A WebSocket connection is established over a standard HTTP connection using a GET request and is then upgraded without impacting the original connection. This means it will work with existing networking infrastructure including firewalls and proxies.

WebSockets is currently supported in the current releases of all major browsers, including Chrome, Brave, Firefox, Edge, Opera, and Safari.

Ioto Implementation

Ioto implements WebSockets for both the HTTP web server and for the URL HTTP client. The WebSockets library implements the core WebSockets protocol, handshaking, and provides a C language API. The web library accepts incoming HTTP connections and upgrades WebSockets requests via to use the WebSockets protocol. Similarly, the url library provides APIs to initiate WebSockets connections via a HTTP client GET request and it then upgrades that connection to use the WebSockets protocol.

The url client program supports WebSockets for load testing purposes.

WebSocket Handshake

A WebSocket connection begins life as a normal HTTP request and is upgraded to the WebSocket protocol. For the web server, the WebSockets connection is activated by a set of WebSocket HTTP headers from the client that describes a desired WebSocket connection. Here is a typical client HTTP request requiring a WebSocket upgrade:

GET /websock/proto/msg HTTP/1.1
Host: example.com
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Protocol: chat, better-chat
Sec-WebSocket-Key: 50cLrugr7h3yAbe5Kpc52Q==
Sec-WebSocket-Version: 13
Origin: http://example.com

WebSockets constructs a handshake response that includes an accepted key and selected protocol. For example:

HTTP/1.1 101 Switching Protocols
Server: Embedthis-http
Date: Sat, 06 Oct 2014 05:10:15 GMT
Connection: Upgrade
Upgrade: WebSocket
Sec-WebSocket-Accept: 58ij/Yod1NTjzqcyjkZbZk6V6v0=
Sec-WebSocket-Protocol: chat
X-Inactivity-Timeout: 600
X-Request-Timeout: 600

After the handshake message has been sent, the server is free to send messages to the client. Once the client receives the handshake, it can send messages to the server. Either side can send at any time thereafter. Communications are thus full-duplex.

Message Types

WebSockets supports several message types:

  • Text in UTF-8
  • Binary
  • Close
  • Ping/Pong

Text Messages

Text messages must be valid UTF-8 strings. The receiving peer will validate and reject non-conforming strings. However, Ioto can be configured to accept invalid UTF-8 strings via the validate Ioto directive in the web.json5 configuration file.

Binary Messages

Binary messages allow the transmission of any content. Messages can be an arbitrary length up to the maximum specified by the WS_MAX_MESSAGE constant or the web.json5 limits.maxMessage directive.

When messages are transmitted, they may be divided into frames of no more than the length specified by the WS_MAX_FRAME constant or the web.json5 limits.maxFrame directive. Incoming message frames are not subject to this limit. WebSockets will aggregate message frames into complete messages before passing to the onRead callback.

Close Message

Ordinarily, WebSocket communications are terminated by sending a Close message. The close message includes a status code and an optional reason string to explain why the connection is being closed.

Ping/Pong Messages

To keep a communications channel alive, it is sometimes necessary to send regular messages to indicate the channel is still being used. Some servers, browsers, or proxies may close an idle connection. The Ping/Pong WebSockets messages are designed to send non-application-level traffic that will prevent the channel from being prematurely closed.

Automatic ping message can be sent from the web server by setting the webSockets.ping directive to the desired frequency. For example:

json5
webSockets {
    ping: '1min'
}

Timeouts

The standard Ioto request and inactivity timeouts can be used for WebSocket communications by defining the timeouts.request and timeouts.inactivity web.json5 directives.

Web Server Configuration

See Web Server WebSockets for details on how to configure WebSockets in the web server. See URL Client for details on how to configure WebSockets in the URL HTTP client.

API

References