How to Build Real-Time Applications with WebSocket API

Learn how to build real-time applications with WebSocket APIs, from the initial HTTP upgrade handshake to sending, receiving, and scaling bidirectional messages securely for chat, order tracking, live dashboards, and other low-latency features.

TRY NANO BANANA FOR FREE

How to Build Real-Time Applications with WebSocket API

TRY NANO BANANA FOR FREE
Contents

Modern applications need instant communication. Users expect live updates, real-time collaboration, and responsive interfaces. WebSockets provide the bidirectional communication needed for these experiences.

Why Regular HTTP Falls Short

HTTP follows a request-response pattern. The client sends a request, the server responds, and the connection closes. Each interaction requires a new connection with overhead.

This works fine for loading web pages. But for real-time applications, it's limiting. Consider a chat application. Users send messages and expect instant delivery. With HTTP, you'd need continuous polling, checking for new messages every second. That's inefficient and creates delay.

WebSockets solve this by establishing persistent connections. Once established, data flows both directions without the HTTP overhead. The connection stays open, ready to transmit messages instantly.

How WebSockets Work

WebSockets start with an HTTP handshake. The client sends a request to upgrade the connection. The server responds, confirming the upgrade. Then the connection transforms into a WebSocket.

After the handshake, neither side needs to follow request-response rules. Either party can send messages at any time. The connection remains open until explicitly closed.

Messages can be text or binary. Text messages work like JSON strings. Binary messages handle files, images, or other binary data efficiently.

The WebSocket API is straightforward:

const socket = new WebSocket('wss://api.petstoreapi.com/v1/ws/chat?token=YOUR_JWT_TOKEN');

The URL uses wss:// for secure connections. Never use unencrypted ws:// in production.

Opening the Connection

Initialize the WebSocket and handle the open event:

const socket = new WebSocket('wss://api.petstoreapi.com/v1/ws/chat?token=YOUR_JWT_TOKEN');

socket.onopen = (event) => {
  console.log('WebSocket connected');
  socket.send(JSON.stringify({
    type: 'subscribe',
    channel: 'orders'
  }));
};

The onopen handler fires when the connection is ready. Send your first message to authenticate or subscribe to channels.

Sending Messages

Send messages using the send method:

function sendOrder(orderData) {
  socket.send(JSON.stringify({
    type: 'order',
    data: orderData
  }));
}

Messages can be strings or Blob/ArrayBuffer objects. JSON.stringify converts objects to strings for transmission.

Receiving Messages

Handle incoming messages with onmessage:

socket.onmessage = (event) => {
  const message = JSON.parse(event.data);

  switch (message.type) {
    case 'order-update':
      updateOrderDisplay(message.data);
      break;
    case 'notification':
      showNotification(message.data);
      break;
    case 'error':
      handleError(message.data);
      break;
  }
};

The event.data property contains the message content. Parse it based on your protocol.

Handling Errors and Closing

Handle errors gracefully:

socket.onerror = (error) => {
  console.error('WebSocket error:', error);
  showConnectionError();
};

The onclose handler fires when the connection ends:

socket.onclose = (event) => {
  console.log('Connection closed:', event.code, event.reason);
  attemptReconnection();
};

The close event includes a code and reason. Codes 1000-2999 are reserved for WebSocket protocol. Codes 3000-4999 are application-specific.

Building a Real-Time Feature

Let's build a real-time order tracking feature using the Pet Store API WebSocket.

First, connect to the WebSocket endpoint:

const ws = new WebSocket('wss://api.petstoreapi.com/v1/ws/chat?token=YOUR_JWT_TOKEN');

ws.onopen = () => {
  // Authenticate after connecting
  ws.send(JSON.stringify({
    type: 'auth',
    token: getAuthToken()
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);

  switch (message.type) {
    case 'order-created':
      addNewOrder(message.data);
      break;
    case 'order-updated':
      updateOrderStatus(message.data);
      break;
    case 'order-shipped':
      markAsShipped(message.data);
      break;
  }
};

This single connection handles all order updates. No polling, no missed updates.

Reconnection Strategies

Network issues cause disconnections. Implement robust reconnection:

let reconnectAttempts = 0;
const maxReconnectAttempts = 5;

function connect() {
  const ws = new WebSocket('wss://api.petstoreapi.com/v1/ws/chat?token=YOUR_JWT_TOKEN');

  ws.onclose = () => {
    if (reconnectAttempts < maxReconnectAttempts) {
      reconnectAttempts++;
      const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000);
      setTimeout(connect, delay);
    }
  };

  return ws;
}

Exponential backoff prevents overwhelming the server during outages. Cap the delay to avoid excessively long waits.

Scaling WebSockets

At scale, WebSocket servers require special consideration. Each connection consumes server memory. A server can handle thousands but not hundreds of thousands.

Use a message broker for horizontal scaling:

  1. WebSocket servers connect to Redis or similar
  2. Messages publish to channels
  3. All WebSocket servers subscribe to relevant channels
  4. Each server forwards messages to its connected clients

This architecture distributes connections across multiple servers while maintaining message broadcasting.

Security Considerations

WebSocket security requires attention. The same-origin policy doesn't apply after connection upgrade. Servers must validate origins explicitly.

Implement authentication at connection time:

// Server-side validation
wss.on('connection', (ws, req) => {
  const token = req.url.query.token;

  if (!validateToken(token)) {
    ws.close(4001, 'Invalid token');
    return;
  }

  ws.userId = getUserId(token);
});

Validate every message from clients. Don't trust any client data.

Use secure WebSocket connections (wss://). This encrypts all traffic, preventing eavesdropping.

When to Use WebSockets

WebSockets excel in specific scenarios. Choose WebSockets when:

  • Users send messages that others receive instantly
  • Low latency matters significantly
  • You maintain persistent user sessions
  • You need to push data from server continuously

Skip WebSockets for simple request-response patterns. REST APIs handle those efficiently without WebSocket complexity.

Pet Store API WebSocket

The Pet Store API supports WebSocket connections for real-time features. Connect to handle instant updates for orders, inventory, and notifications.

Explore the WebSocket documentation at docs.petstoreapi.com. Authentication works through the initial connection message. Subscribe to channels based on your needs.

WebSockets unlock real-time capabilities that differentiate your application. The persistent connections enable experiences impossible with traditional HTTP.