AY

Web Sockets vs Server-Sent Events vs Long Polling

JavaScript

Alex | Last updated: April 15, 2024

Modern web applications are expected to be real-time. So far as I know, there are three mainstream client-server communication methods that allow for as close to real-time as we can get at the moment:

  1. Long Polling
  2. Server-Sent Events
  3. WebSockets

Long Polling

Long polling is a hackish solution to simulate real-time client-server communication.

Its most hackish ancestor, just traditional “polling,” involved consistent server fetches over constant intervals. A basic implementation might look something like this:

function poll() {
    fetch('some_url_goes_here')
        .then((response) => {
            console.log('Data:' response.data);
            // Do something with response.data
        })   
        .catch((error) => {
            console.error(error);
            // Handle error
        })
}

setInterval(poll, 5000); // Execute poll every 5 seconds

As you can imagine, this approach to “real-time” means plenty of unnecessary server calls and quite a bit of overhead.

Long polling improves upon this method by emulating server push communication via a persistent server connection —instead of repeatedly requesting data at regular intervals—that stays open until the server returns some data, at which point the client requests a new server connection.

In short, it’s a server request loop that might look something like this:

function longPoll() {
    fetch('some_url_goes_here')
        .then((response) => {
            console.log('Data:', response.data);
            // Do something with response.adta
            longPoll(); // Establish a new network connection
        })
        ,catch((error) => {
            console.error(error);
            // handle error
            setTimeout(longPoll, 5000); // Attempt to reestablish connection
        })
}

longPoll(); // Initiate long poll

This is an improvement insofar as network requests are only made once new data is available, but some drawbacks include relatively high latency and code complexity to ensure clients receive all events and updates—especially in edge caes, such as network reconnection.

Server-Sent Events

Server-sent events are a way to maintain a one-way, “read-only” connection, whereby a server can send live updates to a client—but a client cannot send writes over the same connection.

These connections can be written using the EventSource API.

const eventSource = new EventSource('url_to_event_source')

eventSource.onmessage = (event) => {
    console.log('Event message received': event.data);
    // Handle generic message event here
}

eventSource.onerror = (event) => {
    console.log('Error');
    // Handle error event here
}

Some benefits to server-sent events include:

The obvious drawback of server-sent events is its unidirectionality; while it’s ideal for features such as live investment tracking, relaying of tournament scores, or other read-only bits of information, user interactions must be implemented through other channels.

Other drawbacks are that clients are limited to a maximum of six server-sent event connections (when not using server-sent events over HTTP/2), and that data can only be UTF-8—no binary data.

WebSockets

The WebSocket API enables the implementation of a full-duplex interactive communication session between a client and a server via a single, lasting TCP connection. Like server-sent events, WebSockets enjoy lower-latencies and do not require the overhead of traditional HTTP request-response cycles.

WebSocket implementation using the WebSocket API looks similar to that of server-sent events:

const socket = new WebSocket('ws_url_to_event_source')

socket.onopen = (event) => {
    console.log('Connection established');
    const payload = 'Create some payload here';
    socket.send(payload);
}

socket.onmessage = (event) => {
    console.log('Event message received', event.data);
    // Handle socket event here
}

socket.onerror = (event) => {
    console.log('Error');
    // Handle error event here
}

There are a few crucial differences between WebSockets and server-sent events:

To handle WebSocket connection issues, developers often use a ping-pong heartbeat mechanism to ensure connections are not closed and implement functionality via the socket’s onclose method to handle network reconnection.

Summary

There are other protocols as well, such as the WebTransport protocl and WebRTC, but neither are among the most commonly used methods of implementing real-time interactive web applications, which are summarized below:

Long PollingWebSocketsServer-Sent Events
Connection DirectionIn general, one-way from server to client.Bi-directional between server and client.One-way, read-only connection from server to client.
HTTP OverheadHigh. (HTTP headers sent on every request)Low. (HTTP/1.1 used to establish connection via handshake)Low. (HTTP used to establish connection). Can be used over both HTTP/2 and HTTP/1.1.
Reconnect HandlingManually coded timeout.Manually coded onclose handler.Automatic reconnect attempts.
Backwards CompatabilityPretty much completely compatible.Not polyfillable, but compatible with most browsers.Polyfillable.