Two-way communication Server push and WebSockets

Server push

Problem: AJAX is one-way (request/response)

  1. The client sends data in the request,
  2. The server replies with data.
  • A server cannot initiate data transfers;
  • A server cannot initiate actions on the client (reverse remote procedure call).

Simulate two-way communication (see Comet)

  • Short polling, Long polling, Streaming.

True two-way communication

  • EventSource, WebSockets, …

Polling

Useful for: notifications, backwards compatibility

Short polling

  1. The client regularly sends AJAX request (i.e., every few seconds),
  2. If there’s new data, the server sends it in the response.

Long polling, Streaming

  1. The client opens a HTTP with the server,
  2. The server sends HTTP headers, does not close connection

    HTTP/1.1 200 OK
    Connection: keep-alive
    
  3. When new data arrives, the server sends it in the response body;
  4. (only in long polling) the server shuts down the connection after the first batch of data, client opens a new connection.

Polling

Pros

  • Backwards compatibility,
  • No special server support (for short polling),

Cons

  • Expensive in bandwidth and resources (HTTP overhead),
  • Latency.

Web Sockets

Full-duplex communication protocol, HTTP-compatible.

  • Application-level protocol over TCP: no HTTP overhead;
  • Meant to use the same port as HTTP (80 or 443).
GET /app/socket HTTP/1.1
Upgrade: websocket
Connection: Upgrade
...
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
...
  1. The client asks for a web socket connection via HTTP,
  2. The server replies with 101 Switching Protocols,
  3. The server and the client establish a Web Socket TCP connection (ws:// or wss:// schema).

WebSocket example: server

Example using the ws package:

var WebSocket = require('ws');

var server = new WebSocket.Server({ port: 80 });

server.on('connection', function connection(ws) {
  ws.on('message', function(message) {
    console.log('received:', message);
  });

  ws.send('something');
});

WebSocket example: client (browser)

Example using the native browser API:

var ws = new WebSocket('ws://www.example.com/');

ws.addEventListener('open', function(e) {
  ws.addEventListener('message', function(e) {
    console.log('received:', e.data);
  });
    
  ws.send('something else');
});

Server example with Express and ws (see demo)

var http = require('http');
var express = require('express');
var WebSocket = require('ws');

var app = express();
var server = http.createServer(app);
var wsserver = new WebSocket.Server({ server: server });

wsserver.on('connection', function connection(ws) {
  ws.on('message', function(message) {
    console.log('received:', message);
  });

  ws.send('something');
});

server.listen(80);

Web Sockets

Pros

  • Two-way
  • Little overhead,
  • Supported by all modern browsers.

Cons

  • Need special support in the server.
  • Not compatible with old browsers.
  • Hard to mix with old style web programming (best to go full-WebSockets or nothing).

Node.js libraries

Other server push techniques

Event streams and EventSource (demo)

  • A standardized version of HTTP streaming,
  • Uses special Content-Type: text/event-stream,
  • Standardized browser support via the EventSource API.

Pros: easy to implement, compatible with old-style AJAX.
Cons: HTTP overhead, one-way (server to client), inconsistent support.

Service workers and Push notifications

Pros: powerful, enables unique features (mobile oriented).
Cons: still experimental, advanced API.

References

WebSockets

Other technologies

Fork me on GitHub