Skip to content

Node.js on VIP

WebSockets

VIP supports WebSocket connections for Node.js environments. The WebSocket API allows long-running, two-way communication between a client and a server. WebSockets can be a performant alternative to traditional polling approaches and potentially useful in a variety of use cases including live blogs, chat applications, on-site notifications, and event subscriptions.

HTTP request headers

WebSocket client connections require two HTTP request headers to be set in order to set up a handshake with the server:

  • Upgrade: websocket
  • Connection: upgrade

In many client libraries, these headers are set automatically.

Path requirements

Paths for WebSocket connections must begin with either /_ws/ or /socket.io/.

Examples of valid paths:

  • /_ws/
  • /_ws/liveblog
  • /_ws/chat/user/12345
  • /socket.io/subscribe/

Examples of invalid paths:

  • /_ws
  • /socket.io
  • /liveblog/_ws/

Reestablishing connections

WebSocket connections are long-lived but cannot last forever. Normal application lifecycle events such as deploys and autoscaling, as well as network disruptions experienced by users, can close open WebSocket connections without warning.

Because of this, application code should be designed to expect these events and to automatically reestablish WebSocket connections whenever they are disrupted.

Socket.io and long-polling

Socket.io is a popular library for implementing bidirectional communication in Node.js applications. However, Socket.io predates the widespread adoption of WebSockets and does not default to using them.

Instead, Socket.io first establishes a connection via long-polling transport before possibly upgrading to a WebSocket. The long-polling transport is not supported on VIP because it requires consecutive requests to be routed automatically to the same container (sometimes called “sticky sessions”).

To avoid this issue, configure Node.js clients to only use the WebSocket transport.

Example implementation

An example of WebSocket implementation can be found in the Node.js skeleton. The example demonstrates how to integrate a WebSocket server with a separate web server. This allows a traditional website to be served and provides a single WebSocket server instance that is shared by all connections. Creating a new WebSocket server instance for each connection—intentionally or accidentally—can quickly lead to performance problems.

Last updated: April 21, 2022