In this lesson, you will learn how a standard HTTP request transforms into a persistent, stateful WebSocket connection through the "Upgrade" handshake mechanism.
The Bridge from HTTP to WebSockets
Every WebSocket connection starts its life as a normal HTTP GET request. Because WebSockets run over the same ports as HTTP (80 or 443), they use a process called "upgrading" to negotiate the switch from the request-response model to a bidirectional stream.
When a client wants to initiate a connection, it sends a header Upgrade: websocket. The server, if configured to support WebSockets, inspects this header and responds with a 101 Switching Protocols status code. Once this handshake completes, the HTTP connection is effectively "hijacked," and the browser and server can now exchange raw data frames without the overhead of HTTP headers.
The Handshake in Action
In Node.js, you handle this by listening for the upgrade event on the core http.Server. Here is how that handshake inspection looks conceptually:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200);
res.end('Standard HTTP response');
});
server.on('upgrade', (req, socket, head) => {
// 1. Verify the 'Upgrade' header
if (req.headers['upgrade'] !== 'websocket') {
socket.end('HTTP/1.1 400 Bad Request');
return;
}
// 2. Perform the handshake (Node.js manages the socket here)
const resHeader = [
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
'\r\n'
].join('\r\n');
socket.write(resHeader);
// Now the socket is raw and stateful!
socket.on('data', (buffer) => {
console.log('Received frame:', buffer);
});
});
The 101 Switching Protocols response acts as the formal acknowledgment that the handshake was successful. At this moment, the server stops treating the request as a transient HTTP transaction and begins maintaining the socket object in memory. This is the transition from a stateless request to a stateful, long-lived connection.
Key Takeaway: The WebSocket handshake is a bridge that uses an HTTP Upgrade header to promote a transient connection into a persistent, bidirectional tunnel between client and server.