WebSocket Protocol Basics and Implementation

Author

Reads 846

Close Up Photo of Network Switch
Credit: pexels.com, Close Up Photo of Network Switch

The WebSocket protocol is a game-changer for real-time web applications. It allows for bidirectional communication between a client and a server, enabling features like live updates and instant messaging.

This is made possible by the use of a persistent connection between the client and server, which eliminates the need for frequent polling or long polling.

With WebSocket, data is sent over this connection as soon as it's available, ensuring that users receive updates in real-time.

The protocol is widely supported by modern browsers and servers, making it a reliable choice for developers.

A different take: Websocket Create Connection

WebSocket Basics

A message in WebSocket is composed of one frame if unfragmented or at least two frames if fragmented.

Fragmentation allows sending messages with initial data available but complete length unknown, which enables multiplexing several streams simultaneously.

An unfragmented message consists of one frame with FIN = 1 and opcode ≠ 0.

A fragmented message is terminated by one frame with FIN = 1 and opcode = 0.

  • An unfragmented message consists of one frame with FIN = 1 and opcode ≠ 0.
  • A fragmented message consists of one frame with FIN = 0 and opcode ≠ 0, followed by zero or more frames with FIN = 0 and opcode = 0, and terminated by one frame with FIN = 1 and opcode = 0.

What is WebSocket

Credit: youtube.com, WebSockets in 100 Seconds & Beyond with Socket.io

A WebSocket is a persistent connection between a client and a server that allows for bidirectional, real-time communication over the web.

This means that once established, a WebSocket connection remains open until it's intentionally closed by either the client or server.

WebSockets use the WebSocket protocol, which is a standardized protocol for establishing and maintaining a WebSocket connection.

The WebSocket protocol is built on top of the TCP/IP protocol and uses a combination of HTTP and TCP/IP to establish a connection.

WebSocket connections are typically established over port 80, the same port used for standard HTTP requests.

This makes it easy to integrate WebSockets into existing web applications, as it doesn't require a separate port or configuration.

If this caught your attention, see: Dns Protocol Port

Client-to-Server Masking

Client-to-server masking is a crucial aspect of WebSocket communication.

A client must mask all frames sent to the server.

The masking process applies XOR between the payload and the masking key.

This algorithm is used to both mask and unmask a frame.

The client is responsible for generating the masking key and applying it to the payload.

Consider reading: Sec Websocket Key

Establishing via HTTP/1.1

Credit: youtube.com, How Web Sockets work | Deep Dive

Establishing a WebSocket connection via HTTP/1.1 involves using the HTTP Upgrade request header, which is not guaranteed in HTTP/1.1 and is not allowed in HTTP/2.

The HTTP Upgrade header is a hop-by-hop header that must be listed in the HTTP Connection header. This is a requirement for initiating a WebSocket connection.

A server is not obligated to change protocols, even if it supports the one the client intends to upgrade to. The server's decision to upgrade or not is entirely up to it.

The client sends an HTTP request with the HTTP Upgrade header, requesting the server to upgrade the connection to the WebSocket protocol. This request is acknowledged by the server with the 101 Switching Protocols HTTP status code.

The client verifies the base64-encoded string in the Sec-Websocket-Accept header, and from that point on, subsequent messages are assumed to be WebSocket. This is how the client knows the connection has been successfully upgraded.

For another approach, see: He Texted after First Date but Not since

WebSocket Protocol

Credit: youtube.com, WebSocket Protocol Explained: Real-Time Communication for Beginners

The WebSocket protocol is a bidirectional communication protocol that allows for full-duplex communication between a client and a server. It starts with a normal HTTP connection that gets upgraded to the WebSocket protocol.

The protocol uses a frame-based message exchange, which includes data, ping, and pong messages. It also includes a closing handshake, where one side sends a close message, and the other side responds with a close message, ending the connection.

Here are the different states of a WebSocket connection:

• Connecting: The client initiates a connection to the server.

• Open: The connection is established, and both client and server can send messages.

• Closing: One side sends a close message, and the other side responds with a close message.

• Closed: The connection is closed, and no further messages can be sent.

The WebSocket protocol uses a specific handshake process to establish the connection. It starts with an HTTP request from the client to the server, which includes an "Upgrade: websocket" header. The server responds with a 101 Switching Protocols status code, indicating that the connection has been upgraded to WebSocket.

A fresh viewpoint: Mat Leave Email Message

Credit: youtube.com, REST API (HTTP) vs Websockets - Concept Overview With Example

The Sec-WebSocket-Key header is part of the WebSocket handshake. It's a random string of 16 characters, each with an ASCII value between 32 and 127, which is base64 encoded. A different key must be generated for each connection.

The Sec-WebSocket-Accept header is included in the server's response and is used to verify that the server understands WebSockets. It's calculated by appending a specific UUID to the Sec-WebSocket-Key, re-encoding it using base64, and returning it in the response.

The Sec-WebSocket-Extensions header allows the client to ask the server to use specific extensions. The server responds with the Sec-WebSocket-Extensions header to confirm what extensions will be used for the remainder of the connection.

The Sec-WebSocket-Protocol header is used to ask the server to use a specific subprotocol. The server responds with the Sec-WebSocket-Protocol header to confirm which subprotocol will be used.

The Sec-WebSocket-Version header is used to ask the server to use a specific version of the WebSocket protocol. The server responds with the Sec-WebSocket-Version header listing the versions it supports.

The WebSocket protocol has four states: connecting, open, closing, and closed. All communication between clients and servers takes place through the use of the WebSocket frame. A frame is a small header + payload, where the payload is any application data.

Control frames may not be fragmented and must have a payload length not greater than 125 bytes. Non-control frames may not interleave other non-control frames. If either side sends a close frame, the connection moves from open to closing, and all further frames must be discarded.

Server Implementation

Credit: youtube.com, Python websocket server client example

Server implementation can be a complex task, but it's essential to understand the basics. Nginx has supported WebSockets since 2013, implemented in version 1.3.13, and can act as a reverse proxy and load balancer of WebSocket applications.

Apache HTTP Server has also supported WebSockets since July 2013, implemented in version 2.4.5. Internet Information Services added support for WebSockets in version 8, which was released with Windows Server 2012.

Some popular servers support WebSockets, including Nginx, Apache HTTP Server, and Microsoft IIS. If you're using ASP.NET Core, you can enable WebSocket support with the app.UseWebSockets(); middleware.

Server Implementations

Some popular web servers support WebSockets, including Nginx, which added support in version 1.3.13. Apache HTTP Server also supports WebSockets, implemented in version 2.4.5.

Nginx has been supporting WebSockets since 2013, and it can even act as a reverse proxy and load balancer of WebSocket applications. This makes it a great option for large-scale WebSocket deployments.

Credit: youtube.com, Implementing Complex TCP Server | Udemy Course | TCP Socket Programming

Internet Information Services, or IIS, added support for WebSockets in version 8, which was released with Windows Server 2012. This means that IIS is a good choice for Windows-based WebSocket servers.

lighttpd, a lightweight web server, has supported WebSockets since 2017, implemented in version 1.4.46. It can also act as a reverse proxy and load balancer of WebSocket applications, and it supports WebSockets over HTTP/2 since version 1.4.65.

Here's a list of some popular web servers that support WebSockets:

  • Nginx (version 1.3.13)
  • Apache HTTP Server (version 2.4.5)
  • Internet Information Services (version 8)
  • lighttpd (version 1.4.46)
  • Eclipse Mosquitto (MQTT broker with WebSocket support)

ASP.NET Core also has support for WebSockets using the app.UseWebSockets(); middleware. This makes it easy to add WebSocket support to ASP.NET Core applications.

Proxy Traversal

Proxy traversal is a crucial aspect of WebSocket protocol client implementations. It involves detecting whether a user agent is configured to use a proxy when connecting to a destination host and port.

Some proxy servers are transparent and work fine with WebSocket, while others will prevent WebSocket from working correctly. This can cause the connection to fail.

Additional proxy-server configuration may be required to ensure WebSocket functionality. Certain proxy servers may need to be upgraded to support WebSocket.

If unencrypted WebSocket traffic flows through an explicit or a transparent proxy server without WebSockets support, the connection will likely fail.

Connection Lifespan

Close-up of ethernet cables connected to a network switch panel in a data center.
Credit: pexels.com, Close-up of ethernet cables connected to a network switch panel in a data center.

A WebSocket connection has four states: connecting, open, closing, and closed. The connection lifespan is a crucial aspect of server implementation.

In the open state, both the client and server can send any type of message to each other at any time, with some minor restrictions. Control frames, for instance, may not be fragmented, and if they have a payload, the first two bytes must be a WebSocket status code.

Non-control frames, on the other hand, may not interleave other non-control frames. If a frame's opcode indicates a close, the connection moves from open to closing, and all further frames must be discarded.

Here are the four states of a WebSocket connection:

To handle client disconnects, the server can set a timeout after nothing is received from the client within a certain time window. If the client isn't always sending messages, it can use a timer to send a ping message every X seconds.

Add HTTP/2 to Existing Controllers

Credit: youtube.com, HTTP/2 development: A hands-on approach (part 1)

Adding HTTP/2 to existing controllers is a straightforward process that requires a simple update to your route attribute.

NET 7 introduced WebSockets over HTTP/2 support for Kestrel, which means you can now use this feature with your existing controllers.

If you previously used [HttpGet("/path")] on your controller action method for WebSocket requests, update it to use [Route("/path")] instead.

This change is necessary because HTTP/2 WebSockets use CONNECT requests rather than GET.

Disable Socket.io on Node.js

Disabling Socket.io on Node.js is crucial for successful app deployment.

If you're using the WebSocket support in socket.io on Node.js, you'll need to disable the default IIS WebSocket module to prevent conflicts.

The IIS WebSocket module will attempt to handle WebSocket communication if not disabled, which can lead to issues with your app.

To disable the IIS WebSocket module, use the webSocket element in web.config or applicationHost.config.

This step is essential to ensure that Node.js handles the WebSocket communication as intended, rather than the IIS module.

See what others are reading: Signal App Video Call

Security and Configuration

Credit: youtube.com, What Is A Websocket Client? - SecurityFirstCorp.com

Security is a top priority when working with WebSockets, and one of the main concerns is cross-site WebSocket hijacking attacks. These attacks can occur when the connection is authenticated with cookies or HTTP authentication, so it's essential to validate the "Origin" header against the expected origins during connection establishment.

To prevent such attacks, WebSocket servers must use tokens or similar protection mechanisms to authenticate the WebSocket connection when sensitive data is being transferred over the WebSocket. This was demonstrated in 2020 with the Cable Haunt vulnerability.

To configure the middleware, you can add the WebSockets middleware in Program.cs and set the following settings: KeepAliveInterval - How frequently to send "ping" frames to the client to ensure proxies keep the connection open.AllowedOrigins - A list of allowed Origin header values for WebSocket requests. By default, all origins are allowed, but you should specify the allowed origins to ensure only trusted clients can connect.

IIS/IIS Express Support

Man with small modern device for storage and transfer information
Credit: pexels.com, Man with small modern device for storage and transfer information

Windows Server 2012 or later and Windows 8 or later with IIS/IIS Express 8 or later have support for the WebSocket protocol, but not for WebSockets over HTTP/2. This means you can take advantage of WebSockets on these systems, but not with HTTP/2.

WebSockets are always enabled when using IIS Express, so you don't need to worry about configuring them manually in this case.

See what others are reading: Websocket vs Http

Security Considerations

Security considerations are crucial when it comes to WebSockets. Unlike regular cross-domain HTTP requests, WebSocket requests are not restricted by the same-origin policy.

This means that WebSocket servers must validate the "Origin" header against the expected origins during connection establishment to avoid cross-site WebSocket hijacking attacks. These attacks are similar to cross-site request forgery and can be possible when the connection is authenticated with cookies or HTTP authentication.

WebSocket servers should use tokens or similar protection mechanisms to authenticate the WebSocket connection when sensitive data is being transferred over the WebSocket. A live example of vulnerability was seen in 2020 in the form of Cable Haunt.

Ethernet Cables Plugged in Network Switch
Credit: pexels.com, Ethernet Cables Plugged in Network Switch

To ensure security, always check the Origin header when making WebSocket requests. Here's a list of best practices to follow:

  • Validate the "Origin" header against the expected origins during connection establishment.
  • Use tokens or similar protection mechanisms to authenticate the WebSocket connection when sensitive data is being transferred.

By following these best practices, you can significantly reduce the risk of cross-site WebSocket hijacking attacks.

Sec Key

The Sec-WebSocket-Key header is part of the WebSocket handshake, calculated by base64 encoding a random string of 16 characters.

A different key must be randomly generated for each connection, making it a unique identifier for each WebSocket connection.

The key is read by the server and a corresponding response is returned to the client, which is then used for verification purposes.

The server appends UUID 258EAFA5-E914-47DA-95CA- to the Sec-WebSocket-Key and re-encodes it using base64.

This mechanism allows the client to verify that the server indeed understands WebSockets.

Sec Extensions

The Sec-WebSocket-Extensions header is part of the WebSocket handshake, sent by the client to ask the server to use a specific set of extensions.

This header can be included more than one time or as a common-delimited list of extensions on a single line, chosen from the IANA WebSocket Extension Name Registry.

Individual using a VPN application on a laptop at a desk in a modern office setting.
Credit: pexels.com, Individual using a VPN application on a laptop at a desk in a modern office setting.

If an extension requires a parameter, it can be included by preceding the parameter with a semicolon.

The server will respond with the Sec-WebSocket-Extensions header to confirm what protocol-level extensions will be used for the remainder of the connection.

The server will not include more than one instance of this header in the response.

You might enjoy: Self Hosted Chat Server

Compression

Compression can make an app subject to CRIME/BREACH attacks if enabled over encrypted connections.

If you're sending sensitive information, it's a good idea to avoid enabling compression altogether or use WebSocketMessageFlags.DisableCompression when calling WebSocket.SendAsync.

The WebSockets API in the browser doesn't have configuration for disabling compression per send, so be aware of this limitation.

Compression is negotiated between the client and server when first establishing a connection.

If the compression negotiation isn't accepted by either the server or client, the connection is still established, but it won't use compression when sending and receiving messages.

If you do want to use compression, the accept code must specify that it allows compression, using options like WebSocketAcceptContext.ServerMaxWindowBits and WebSocketAcceptContext.DisableServerContextTakeover.

Client-Side WebSocket

Credit: youtube.com, 8.1 How to Create a WebSocket Client in Python - Fun with WebSockets!

Most modern browsers support the WebSocket protocol, allowing for bidirectional communication between the client and server.

This means you can use WebSockets in your web development projects with a wide range of browsers, including Google Chrome, Mozilla Firefox, and Microsoft Edge.

However, some versions of browsers in certain operating systems have been disabled due to security concerns, so be sure to check compatibility before implementing WebSockets in your project.

Browser Support

Browser support for WebSockets is relatively widespread, but some older versions have security concerns that led to their disabling.

Firefox 6 and later, as well as Safari 6 and later, Google Chrome 14 and later, and Opera 12.10 and later, all support the secure version of the WebSocket protocol. Internet Explorer 10 also supports it.

An older, less secure version was implemented in Opera 11 and Safari 5, as well as the mobile version of Safari in iOS 4.2. The BlackBerry Browser in OS7 also implements WebSockets, but it was disabled in Firefox 4 and 5, and Opera 11 due to vulnerabilities.

Here's a breakdown of the protocol version support across different browsers:

WebSocket in Action

Credit: youtube.com, 1.1 What is WebSocket? - Fun with WebSockets!

WebSocket is used in real-time applications like chat, live notifications, and online games, making it a crucial part of modern web development.

Instant messaging apps like WhatsApp Web, Slack, and Facebook Messenger use WebSocket to sync messages between browsers and phones.

Collaborative editing tools like Google Docs use WebSocket to show changes instantly.

Live presence indicators, chat messages, and meeting controls in Zoom and Microsoft Teams are also made possible by WebSocket.

TradingView uses WebSocket for real-time stock, crypto, and forex price updates.

Online multiplayer games use WebSocket for low-latency player interactions.

Here are some examples of WebSocket in action:

  • WhatsApp Web: instant messaging sync between browser and phone
  • Google Docs: collaborative document editing with instant changes
  • Zoom / Microsoft Teams: live presence indicators, chat messages, and meeting controls
  • TradingView: real-time stock, crypto, and forex price updates
  • Uber: live driver location and ride status updates
  • Online multiplayer games: low-latency player interactions

WebSocket maintains a connection as long as the session is open, avoiding the overhead of dropping and reestablishing connections.

Frequently Asked Questions

Is WebSocket an API protocol?

WebSocket is not an API protocol itself, but rather a protocol that enables APIs to offer bidirectional communication. It's a key technology behind many modern APIs, allowing for real-time data exchange between clients and servers.

Is WSS the same as https?

WSS (WebSocket Secure) is not exactly the same as HTTPS, but it uses the same encryption protocols (SSL/TLS) to secure data transmission. Think of WSS as a secure, real-time communication channel built on top of HTTPS.

Does WSS use port 443?

Yes, WSS (WebSockets Secure) uses port 443, the same as HTTPS. This ensures secure communication between the client and server.

Thomas Goodwin

Lead Writer

Thomas Goodwin is a seasoned writer with a passion for exploring the intersection of technology and business. With a keen eye for detail and a knack for simplifying complex concepts, he has established himself as a trusted voice in the tech industry. Thomas's writing portfolio spans a range of topics, including Azure Virtual Desktop and Cloud Computing Costs.

Love What You Read? Stay Updated!

Join our community for insights, tips, and more.