📄 Page
1
The WebSocket Handbook Learn about the technology underpinning the realtime web and build your first web app powered by WebSockets
📄 Page
2
v2.0 • February 2022 The WebSocket Handbook By Alex Diaconu Special Thanks In no particular order: Jo Franchetti (for contributing Chapter 4 and building the demo app), Ramiro Nuñez Dosio (for encouraging me to write the book in the first place, giving valuable advice, and removing blockers), Jonathan Mercier-Ganady (for the technical review), Jo Stichbury (for the editorial review), Leonie Wharton, Chris Hipson, Jamie Watson (for all the design work involved), Ben Gamble (for helping me define and write Chapter 5). About the Author Alex Diaconu is a WebSocket enthusiast who has spent most of his professional career working alongside engineering teams, technical product managers, and system architects, while writing about web technologies. Alex is currently a Technical Content Writer at Ably, where he is exploring the world of realtime tech, and writing about the many challenges of event-driven architectures and distributed systems. In his free time, Alex likes going on hiking trips, watching his favourite football team, playing basketball, and reading sci-fi & history.
📄 Page
3
Contents The WebSocket Handbook Preface 06 Who this book is for 06 What this book covers 07 Chapter 1: The Road to WebSockets 08 The World Wide Web is born 08 JavaScript joins the fold 10 Hatching the realtime web 11 AJAX 11 Comet 13 Long polling 13 HTTP streaming 13 Limitations of HTTP 15 Enter WebSockets 17 Comparing WebSockets and HTTP 18 Use cases and benefits 18 Adoption 19 Chapter 2: The WebSocket Protocol 20 Protocol overview 20 URI schemes and syntax 21 Opening handshake 22 Client request 22 Server response 23 Opening handshake headers 24 Sec-WebSocket-Key and Sec-WebSocket-Accept 26 Message frames 27 FIN bit and fragmentation 28 RSV 1-3 29 Opcodes 29
📄 Page
4
Masking 30 Payload length 30 Payload data 31 Closing handshake 31 Subprotocols 34 Extensions 35 Security 35 Chapter 3: The WebSocket API 37 Overview 37 The WebSocket server 38 The WebSocket constructor 38 Events 39 Open 39 Message 40 Error 40 Close 41 Methods 41 send() 41 close() 42 Properties 43 binaryType 43 bufferedAmount 43 extensions 44 “onevent” properties 44 protocol 45 readyState 45 url 45 Chapter 4: Building a Web App with WebSockets 46 WebSocket clients and servers 46 ws — a Node.js WebSocket library 47 Building an interactive cursor position-sharing demo with ws 47 Setting up the WebSocket server 47 WebSockets on the client-side 49 Running the demo 52 SockJS — a JavaScript library to provide WebSocket-like communication 55 Updating the interactive cursor position sharing demo to use SockJS 55
📄 Page
5
Running the demo with SockJS 57 Scaling the web app 58 What makes WebSockets hard to scale? 58 Chapter 5: WebSockets at Scale 59 The scalability of your server layer 59 Load balancing 61 Load balancing algorithms 62 Architecting your system for scale 64 Fallback transports 66 Managing WebSocket connections and messages 68 New connections 68 Monitoring WebSockets 69 Load shedding 69 Restoring connections 70 Automatic reconnections 70 Reconnections with continuity 72 Heartbeats 72 Backpressure 73 A quick note on fault tolerance 74 WebSockets at scale checklist 75 Resources 77 References (ordered alphabetically) 77 Videos 78 Further reading 78 Open-source WebSocket libraries 78 Final thoughts 79 About Ably 80
📄 Page
6
06 The WebSocket Handbook Preface Preface Our everyday digital experiences are in the midst of a realtime revolution. Whether we’re talking about virtual events, EdTech, news and financial information, IoT devices, asset tracking and logistics, live score updates, or gaming, consumers increasingly expect realtime digital experiences as standard. And what better to power these realtime interactions than WebSockets? Until the emergence of WebSockets, the “realtime” web was difficult to achieve and slower than we’re used to nowadays; it was delivered by hacking existing HTTP-based technologies that were not designed and optimized for realtime applications. WebSockets mark a turning point for web development. Designed to be event-driven & full-duplex, and optimized for minimum overhead and low latency, WebSockets have become a preferred choice for many organizations and developers seeking to build interactive, realtime digital experiences that provide delightful user experiences. Who this book is for This book is intended for developers (and any other types of technical audiences) who want to: • Explore the core building blocks of the WebSocket technology, its characteristics, and its advantages. • Build realtime web apps with WebSockets. • Discover the benefits of event-driven architectures with WebSockets. • Learn about the engineering challenges you will face when building scalable systems with WebSockets. Knowledge of/familiarity with HTML, JavaScript (and Node.js), HTTP, web APIs, and web development is required to get the most out of this book.
📄 Page
7
07 The WebSocket Handbook Preface What this book covers Chapter 1: The Road to WebSockets looks at how web technologies evolved since the inception of the World Wide Web, culminating with the emergence of WebSockets, a vastly superior improvement on HTTP for building realtime web apps. Chapter 2: The WebSocket Protocol covers key considerations related to the WebSocket protocol. You’ll find out how to establish a WebSocket connection and exchange messages, what kind of data can be sent over WebSockets, what types of extensions and subprotocols you can use to augment WebSockets. Chapter 3: The WebSocket API provides details about the constituent components of the WebSocket API — its events, methods, and properties, alongside usage examples for each of them. Chapter 4: Building a Web App with WebSockets provides detailed, step-by-step instructions on building a realtime web app with WebSockets and Node.js: an interactive cursor position-sharing demo. Chapter 5: WebSockets at Scale is an overview of the numerous engineering decisions and technical trade-offs involved in building a system at scale. Specifically, a system that is capable of handling thousands or even millions of concurrent end-user devices as they connect, consume, and send messages over WebSockets. Resources — a collection of articles, videos, and WebSocket solutions you might want to explore. The WebSocket technology is a vast and complex topic; this second version of the ebook does not intend to cover everything there is to know about it. In future iterations, we plan to: • Add more details to the existing chapters. • Provide more examples and walkthroughs for building apps with WebSockets. • Cover additional aspects that are currently out of scope, such as WebSocket security, and alternatives to WebSockets.
📄 Page
8
08 The WebSocket Handbook Chapter 1: The Road to WebSockets CHAPTER 1 The Road to WebSockets During the 1990s, the web rapidly grew into the dominant way to exchange information. Increasing numbers of users became accustomed to the experience of browsing the web, while browser providers constantly released new features and enhancements. The first realtime web apps started to appear in the 2000s, attempting to deliver responsive, dynamic, and interactive end-user experiences. However, at that time, the realtime web was difficult to achieve and slower than we’re used to nowadays; it was delivered by hacking existing HTTP-based technologies that were not designed and optimized for realtime applications. It quickly became obvious that a better alternative was needed. In this first chapter, we’ll look at how web technologies evolved, culminating with the emergence of WebSockets, a vastly superior improvement on HTTP for building realtime web apps. The World Wide Web is born In 1989, while working at the European Organization for Nuclear Research (CERN) as a software engineer, Tim Berners-Lee became frustrated with how difficult it was to access information stored on different computers (and, on top of that, running different types of software). This prompted Berners-Lee to develop a project called “WorldWideWeb”. The project proposed a “web” of hypertext documents, which could be viewed by browsers over the internet using a client-server architecture. The web had the potential to connect the world in a way that was not previously possible, and made it much easier for people everywhere to get information, share, and communicate. Initially used at CERN, the web was soon made available to the world, with the first websites for everyday use starting to appear in 1993-1994.
📄 Page
9
09 The WebSocket Handbook Chapter 1: The Road to WebSockets Berners-Lee managed to create the web by combining two existing technologies: hypertext and the internet. In the process, he developed three core building blocks: • HTML. The markup (formatting) language of the web. • URI. An “address” (similar to a postal address) that is unique and used to identify each resource on the web. • HTTP. Protocol used for requesting and receiving resources over the web. This initial version of HTTP1 (commonly known as HTTP/0.9) that Berners-Lee developed was incredibly basic. Requests consisted of a single line and started with the only supported method, GET, followed by the path to the resource: GET /mypage.html The hypertext-only response was extremely simple as well: <HTML> My HTML page </HTML> There were no HTTP headers, status codes, URLs, or versioning, and the connection was terminated immediately after receiving the response. Since interest in the web was skyrocketing, and with HTTP/0.9 being severely limited, both browsers and servers quickly made the protocol more versatile by adding new capabilities. Some key changes: • Header fields including rich metadata about the request and response (HTTP version number, status code, content type). • Two new methods — HEAD and POST. • Additional content types (e.g., scripts, stylesheets, or media), so that the response was no longer restricted to hypertext. These modifications were not done in an orderly or agreed-upon fashion, leading to different flavors of HTTP/0.9 in the wild, in turn causing interoperability problems. To resolve these issues, an HTTP Working Group2 was set up, and in 1996, published HTTP/1.03 (defined via RFC 1945). It was an informational RFC, merely documenting all the usages at the time. As such, HTTP/1.0 is not considered a formal specification or an internet standard. 1 The Original HTTP as defined in 1991 2 The IETF HTTP Working Group 3 RFC 1945: Hypertext Transfer Protocol - HTTP/1.0
📄 Page
10
10 The WebSocket Handbook Chapter 1: The Road to WebSockets In parallel with the efforts made on HTTP/1.0, work to properly standardize HTTP was in progress. The first standardized version of the protocol, HTTP/1.1, was initially defined in RFC 20684 and released in January 1997. Several subsequent HTTP/1.1 RFCs5 have been released since then, most recently in 2014. HTTP/1.1 introduces many feature enhancements and performance optimizations, including: • Persistent and pipelined connections. • Virtual hosting. • Content negotiation, chunked transfer, compression, and decompression. • Cache support. • More methods, bringing the total to seven — GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS. JavaScript joins the fold While HTTP was maturing and being standardized, interest and adoption of the web were growing rapidly. A competition (the so-called “browser wars”) for dominance in the usage share of web browsers quickly commenced, initially pitting Microsoft’s Internet Explorer against Netscape’s Navigator. Both companies wanted to have the best browser, so features and capabilities were inevitably added on a regular basis to their browsers. This competition for supremacy was a catalyst for fast technological breakthroughs. In 1995, Netscape hired Brendan Eich with the goal of embedding scripting capabilities into their Netscape Navigator browser. Thus, JavaScript was born. The first version of the language was simple, and you could only use it for a few things, such as basic validation of input fields before submitting an HTML form to the server. Limited as it was back then, JavaScript brought dynamic experiences to a web that had been fully static until that point. Progressively, JavaScript was enhanced, standardized, and adopted by all browsers, becoming one of the core technologies of the web as we know it today. 4 RFC 2068: Hypertext Transfer Protocol - HTTP/1.1 5 IETF HTTP Working Group, HTTP Documentation, Core Specifications
📄 Page
11
11 The WebSocket Handbook Chapter 1: The Road to WebSockets Hatching the realtime web The first web applications started to appear in the late ‘90s and used technologies like JavaScript and HTTP. Browsers were already ubiquitous, and users were growing accustomed to the whole experience. Web technologies were constantly evolving, and soon, attempts were made to deliver realtime web apps with rich, interactive, and responsive end-user experiences. We will now look at the main HTTP-centric design models that emerged for developing realtime apps: AJAX and Comet. AJAX AJAX (short for Asynchronous JavaScript and XML) is a method of asynchronously exchanging data with a server in the background and updating parts of a web page — without the need for an entire page refresh (postback). Publicly used as a term for the first time in 20056, AJAX encompasses several technologies: • HTML (or XHTML) and CSS for presentation. • Document Object Model (DOM) for dynamic display and interaction. • XML or JSON for data interchange, and XSLT for XML manipulation. • XMLHttpRequest7 (XHR) object for asynchronous communication. • JavaScript to bind everything together. It’s worth emphasizing the importance of XMLHttpRequest, a built-in browser object that allows you to make HTTP requests in JavaScript. The concept behind XHR was initially created at Microsoft and included in Internet Explorer 5, in 1999. In just a few years, XMLHttpRequest would benefit from widespread adoption, being implemented by Mozilla Firefox, Safari, Opera, and other browsers. Let’s now look at how AJAX works, by comparing it to the classic model of building a web app. 6 Jesse James Garrett, Ajax: A New Approach to Web Applications 7 XMLHttpRequest Living Standard
📄 Page
12
12 The WebSocket Handbook Chapter 1: The Road to WebSockets Figure 1.1: Classic model of a web app vs. the AJAX model In a classic model, most user actions in the UI trigger an HTTP request sent to the server. The server processes the request and returns the entire HTML page to the client. In comparison, AJAX introduces an intermediary (an AJAX engine) between the user and the server. Although it might seem counterintuitive, the intermediary significantly improves responsiveness. Instead of loading the webpage, at the start of the session, the client loads the AJAX engine, which is responsible for: • Regularly polling the server on the client’s behalf. • Rendering the interface the user sees, and updating it with data retrieved from the server. AJAX (and XMLHttpRequest request in particular) can be considered a black swan event for the web. It opened up the potential for web developers to start building truly dynamic, asynchronous, realtime-like web applications that could communicate with the server silently in the background, without interrupting the user’s browsing experience. Google was among the first to adopt the AJAX model in the mid-2000s, initially using it for Google Suggest, and its Gmail and Google Maps products. This sparked widespread interest in AJAX, which quickly became popular and heavily used.
📄 Page
13
13 The WebSocket Handbook Chapter 1: The Road to WebSockets Comet Coined8 in 2006, Comet is a web application design model that allows a web server to push data to the browser. Similar to AJAX, Comet enables asynchronous communication. Unlike classic AJAX (where the client periodically polls the server for updates), Comet uses long-lived HTTP connections to allow the server to push updates whenever they’re available, without the client explicitly requesting them. The Comet model was made famous by organizations such as Google and Meebo. The former initially used Comet to add web-based chat to Gmail, while Meebo used it for their web-based chat app that enabled users to connect to AOL, Yahoo, and Microsoft chat platforms through the browser. In a short time, Comet became a default standard for building responsive, interactive web apps. Several different techniques can be used to deliver the Comet model, the most well- known being long polling9 and HTTP streaming. Let’s now quickly review how these two work. Long polling Essentially a more efficient form of polling, long polling is a technique where the server elects to hold a client’s connection open for as long as possible, delivering a response only after data becomes available or a timeout threshold is reached. Upon receipt of the server response, the client usually issues another request immediately. Long polling is often implemented on the back of XMLHttpRequest, the same object that plays a key role in the AJAX model. HTTP streaming Also known as HTTP server push, HTTP streaming is a data transfer technique that allows a web server to continuously send data to a client over a single HTTP connection that remains open indefinitely. Whenever there’s an update available, the server sends a response, and only closes the connection when explicitly told to do so. HTTP streaming can be achieved by using the chunked transfer encoding mechanism available in HTTP/1.1. With this approach, the server can send response data in chunks of newline-delimited strings, which are processed on the fly by the client. Figure 1.2: High-level overview of long polling 8 Alex Russell, Comet: Low Latency Data for the Browser 9 Long Polling - Concepts and Considerations
📄 Page
14
14 The WebSocket Handbook Chapter 1: The Road to WebSockets Here’s an example of a chunked response: HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked 7\r\n Chunked\r\n 8\r\n Response\r\n 7\r\n Example\r\n 0\r\n \r\n When chunked transfer encoding is used, each server response includes Transfer-Encoding: chunked, while the Content-Length header is omitted. Server-Sent Events10 (SSE) is another option you can leverage to implement HTTP streaming. SSE is a server push technology commonly used to send message updates or continuous data streams to a browser client. SSE aims to enhance native, cross-browser server-to-client streaming through a JavaScript API called EventSource, standardized11 as part of HTML5 by the World Wide Web Consortium (W3C). Here’s a quick example of opening a stream over SSE: var source = new EventSource('URL_TO_EVENT_STREAM'); source.onopen = function () { console.log('connection to stream has been opened'); }; source.onerror = function (error) { console.log('An error has occurred while receiving stream', error); }; source.onmessage = function (stream) { console.log('received stream', stream); }; 10 Server-Sent Events (SSE): A Conceptual Deep Dive 11 Server-sent events, HTML Living Standard
📄 Page
15
15 The WebSocket Handbook Chapter 1: The Road to WebSockets Limitations of HTTP AJAX and Comet paved the way for creating dynamic, realtime web apps. However — even though they continue to be used nowadays, to a lesser extent — both AJAX and Comet have their shortcomings. Most of their limitations stem from using HTTP as the underlying transport protocol. The problem is that HTTP was initially designed to serve hypermedia resources in a request- response fashion. It hadn’t been optimized to power realtime apps that usually involve high-frequency or ongoing client-server communication, and the ability to react instantly to changes. Hacking HTTP-based technologies to emulate the realtime web was bound to lead to all sorts of drawbacks. We will now cover the main ones (without being exhaustive). Limited scalability HTTP polling, for example, involves sending requests to the server at fixed intervals to see if there’s any new update to retrieve. High polling frequencies result in increased network traffic and server demands; this doesn’t scale well, especially as the number of concurrent users rises. Low polling frequencies will be less taxing on the server, but they may result in delivery of stale information that has lost (part of) its value. Although an improvement on regular polling, long polling is also intensive on the server, and handling thousands of simultaneous long polling requests requires huge amounts of resources. Unreliable message ordering and delivery guarantees Reliable message ordering can be an issue, since it’s possible for multiple HTTP requests from the same client to be in flight simultaneously. Due to various factors, such as unreliable network conditions, there’s no guarantee that the requests issued by the client and the responses returned by the server will reach their destination in the right order. Another problem is that a server may send a response, but network or browser issues may prevent the message from being successfully received. Unless some sort of message receipt confirmation process is implemented, a subsequent call to the server may result in missed messages. Depending on the server implementation, confirmation of message receipt by one client instance may also cause another client instance to never receive an expected message at all, as the server could mistakenly believe that the client has already received the data it is expecting.
📄 Page
16
16 The WebSocket Handbook Chapter 1: The Road to WebSockets Latency The time required to establish a new HTTP connection is significant since it involves a handshake with quite a few back and forth exchanges between the client and the server. In addition to the slow start, we must also consider that HTTP requests are issued sequentially. The next request is only sent once the response to the current request has been received. Depending on network conditions, there can be delays before the client gets a response, and the server receives the next request. All of this leads to increased latency for the user — far from ideal in the context of realtime applications. Although HTTP streaming techniques are better for lower latencies than (long) polling, they are limited themselves (just like any other HTTP-based mechanism) by HTTP headers, which increase message size and cause unnecessary delays. Often, the HTTP headers in the response outweigh the core data being delivered12. No bidirectional streaming A request/response protocol by design, HTTP doesn’t support bidirectional, always- on, realtime communication between client and server over the same connection. You can create the illusion of bidirectional realtime communication by using two HTTP connections. However, the maintenance of these two connections introduces significant overhead on the server, because it takes double the resources to serve a single client. With the web continuously evolving, and user expectations of rich, realtime web-based experiences growing, it was becoming increasingly obvious that an alternative to HTTP was needed. 12 Matthew O’Riordan, Google — polling like it’s the 90s
📄 Page
17
17 The WebSocket Handbook Chapter 1: The Road to WebSockets Enter WebSockets In 2008, the pain and limitations of using Comet when implementing anything resembling realtime were being felt particularly keenly by developers Michael Carter and Ian Hickson. Through collaboration on IRC13 and W3C mailing lists14, they came up with a plan to introduce a new standard for modern, truly realtime communication on the web. Thus, the name “WebSocket’’ was coined. In a nutshell, WebSocket is a technology that enables bidirectional, full-duplex communication between client and server over a persistent, single-socket connection. The intent is to provide what is essentially an as-close-to-raw-as-possible TCP communication layer to web application developers while adding a few abstractions to eliminate certain friction that would otherwise exist concerning the way the web works. A WebSocket connection starts as an HTTP request/response handshake; beyond this handshake, WebSocket and HTTP are fundamentally different. Figure 1.3: WebSockets vs. the traditional HTTP request/response model The WebSocket technology includes two core building blocks: • The WebSocket protocol. Enables communication between clients and servers over the web, and supports transmission of binary data and text strings. For more details, see Chapter 2: The WebSocket Protocol. • The WebSocket API. Allows you to perform necessary actions, like managing the WebSocket connection, sending and receiving messages, and listening for events triggered by the server. For more details, see Chapter 3: The WebSocket API. 13 IRC logs, 18.06.2008 14 W3C mailing lists, TCPConnection feedback
📄 Page
18
18 The WebSocket Handbook Chapter 1: The Road to WebSockets Comparing WebSockets and HTTP While HTTP is request-driven, WebSockets are event-driven. The table below illustrates fundamental differences between the two technologies. WEBSOCKETS HTTP/1.1 Communication Full-duplex Half-duplex Message exchange pattern Bidirectional Request-response Server push Core feature Not natively supported Overhead Moderate overhead to establish the connection, and minimal overhead per message. Moderate overhead per request/connection. State Stateful Stateless Table 1.1: Comparing the characteristics of WebSockets and HTTP/1.1 HTTP and WebSockets are designed for different use cases. For example, HTTP is a good choice if your app relies heavily on CRUD operations, and there’s no need for the user to react to changes quickly. On the other hand, when it comes to scalable, low-latency realtime applications, WebSockets are the way to go. More about this in the next section. Use cases and benefits The WebSocket technology has broad applicability. You can use it for different purposes, such as streaming data between backend services, or connecting a backend with a frontend via long-lasting, full-duplex connections. In a nutshell, WebSockets are an excellent choice for architecting event-driven systems and building realtime apps and services where it’s essential for data to be delivered immediately.
📄 Page
19
19 The WebSocket Handbook Chapter 1: The Road to WebSockets We can broadly group WebSocket use cases into two distinct categories: • Realtime updates, where the communication is unidirectional, and the server is streaming low-latency (and often frequent) updates to the client. Think of live sports updates, alerts, realtime dashboards, or location tracking, to name just a few use cases. • Bidirectional communication, where both the client and the server can send and receive messages. Examples include chat, virtual events, and virtual classrooms (the last two usually involve features like polls, quizzes, and Q&As). WebSockets can also be used to underpin multi-user synchronized collaboration functionality, such as multiple people editing the same document simultaneously. And here are some of the main benefits of using WebSockets: • Improved performance. Compared to HTTP, WebSockets eliminate the need for a new connection with every request, drastically reducing the size of each message (no HTTP headers). This helps save bandwidth, improves latency, and makes WebSockets more scalable than HTTP (note that scaling WebSockets is far from trivial, but at scale, WebSockets are significantly less taxing on the server-side). • Extensibility. Flexibility is ingrained into the design of the WebSocket technology, which allows for the implementation of subprotocols (application-level protocols) and extensions for additional functionality. Learn more about Extensions and Subprotocols. • Fast reaction times. As an event-driven technology, WebSockets allow data to be transferred without the client requesting it. This characteristic is desirable in scenarios where the client needs to react quickly to an event (especially ones it cannot predict, such as a fraud alert). Adoption Initially called TCPConnection, the WebSocket interface made its way into the HTML5 specification15, which was first released as a draft in January 2008. The WebSocket protocol was standardized in 2011 via RFC 6455; more about this in Chapter 2: The WebSocket Protocol. In December 2009, Google Chrome 4 was the first browser to ship full support for WebSockets. Other browser vendors started to follow suit over the next few years; today, all major browsers have full support for WebSockets. Going beyond web browsers, WebSockets can be used to power realtime communication across various types of user agents — for example, mobile apps. Nowadays, WebSockets are a key technology for building scalable realtime web apps. The WebSocket API and protocol have a thriving community, which is reflected by a variety of client and server options (both open-source and commercial), developer ecosystems, and myriad real-life implementations. 15 Web sockets, HTML Living Standard
📄 Page
20
20 The WebSocket Handbook Chapter 2: The WebSockets Protocol CHAPTER 2 The WebSocket Protocol In December 2011, the Internet Engineering Task Force (IETF) standardized the WebSocket protocol through RFC 645516. In coordination with IETF, the Internet Assigned Numbers Authority (IANA) maintains the WebSocket Protocol Registries17, which define many of the codes and parameter identifiers used by the protocol. This chapter covers key considerations related to the WebSocket protocol, as described in RFC 6455. You’ll find out how to establish a WebSocket connection and exchange messages, what kind of data can be sent over WebSockets, what types of extensions and subprotocols you can use to augment WebSockets. Protocol overview The WebSocket protocol enables ongoing, full-duplex, bidirectional communication between web servers and web clients over an underlying TCP connection. In a nutshell, the base WebSocket protocol consists of an opening handshake (upgrading the connection from HTTP to WebSockets), followed by data transfer. After the client and server successfully negotiate the opening handshake, the WebSocket connection acts as a persistent full-duplex communication channel where each side can, independently, send data at will. Clients and servers transfer data back and forth in conceptual units referred to as messages, which, as we describe shortly, can consist of one or more frames. Once the WebSocket connection has served its purpose, it can be terminated via a closing handshake. 16 RFC 6455: The WebSocket Protocol 17 IANA WebSocket Protocol Registries