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:
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
- RFC 6455 - The WebSockets Protocol
- WebSocket API - The Javascript WebSockets API
- WebSockets Wikipedia - WebSockets Wikipedia