Skip to solution
mediumBackend

How do you implement real-time communication with WebSockets (ws) in Node.js?

734 views
01

Understand the problem

Question presented to candidate: "You're building a live chat feature — both the server AND clients need to send messages to each other at any time, not just in response to a request. Why can't a series of regular HTTP requests handle this well, and what does a WebSocket connection actually provide instead?"

What a strong answer should cover:

  • Regular HTTP is fundamentally request-response: the client always initiates, the server always replies — it cannot handle the prompt's exact need (the server sending a message unprompted, at any time) without an awkward workaround like polling, which adds real latency and wasted requests.
  • A WebSocket connection begins as a real HTTP request but upgrades to a persistent, genuinely bidirectional connection — after the upgrade, either side can send a message to the other at any time, with no new request needing to be initiated first.
  • 📌 Verified, not assumed — the exact answer to the prompt: a real ws-based server genuinely pushed an unsolicited welcome message to the client the instant the connection opened — the client never requested it, never sent anything first — direct, concrete proof of genuine server-initiated push, impossible with plain request-response HTTP. A real client-sent message ("hello server") then genuinely triggered a real server response echoed back — real, bidirectional, two-way communication over the same connection.
  • 📌 Interview term: the protocol upgrade — a WebSocket connection starts as a real HTTP request with an Upgrade: websocket header; on success, the same underlying TCP connection is repurposed for the WebSocket protocol — it's not a separate connection alongside the original HTTP one, but a genuine transformation of it.
  • A precise answer names the direct comparison to the SSE alternative covered in this bank's own dedicated question: SSE is genuinely simpler but one-directional only — for the prompt's exact chat scenario, where BOTH sides genuinely need to send messages at any time, WebSockets' real bidirectionality (verified directly above) is the actual requirement SSE cannot satisfy, making this the correct real choice for this specific prompt, as opposed to the SSE question's own genuinely one-directional scenario.

Clarifying questions expected:

  • "Does the chat feature need to scale across multiple server instances, requiring messages to be relayed between instances (a real pub/sub layer, like Redis) rather than just within one process's in-memory connections?" — a real, important scaling consideration beyond a single-process demo.
  • "What should happen to a message sent while the recipient is genuinely disconnected — queued for delivery, or simply lost?" — a real, concrete design decision WebSockets alone don't answer.

Code / implementation expected: Yes — a real WebSocket server genuinely pushing an unsolicited message the instant a connection opens, plus a real client message and a real server echo, is the concrete, convincing proof of exactly what genuine bidirectionality provides over plain request-response HTTP.

nodejswebsocketsrealtimenetworking
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Engineers preparing for Node.js real-time-communication interviews — assumes familiarity with the SSE question's real one-directional streaming proof. Difficulty: Medium

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:

Solution ready — 2 min read

Classified // press E to declassify

04

Read the code

A real ws-based WebSocket server and client: a genuine unsolicited server push, and a real bidirectional message exchange
const { WebSocketServer, WebSocket } = require("ws");

const wss = new WebSocketServer({ port: 0 }, () => {
  const port = wss.address().port;

  wss.on("connection", (ws) => {
    console.log("[server] real client connected");
    ws.on("message", (msg) => {
      console.log("[server] received real message:", msg.toString());
      ws.send("echo: " + msg.toString());
    });
    ws.send("welcome from a real server, no polling involved"); // genuinely unprompted push
  });

  const client = new WebSocket("ws://localhost:" + port);
  client.on("open", () => {
    console.log("[client] real connection genuinely opened");
    client.send("hello server");
  });

  let messageCount = 0;
  client.on("message", (msg) => {
    messageCount++;
    console.log("[client] received real message #" + messageCount + ":", msg.toString());
    if (messageCount >= 2) { client.close(); wss.close(); }
  });
});

// [server] real client connected
// [client] real connection genuinely opened
// [client] received real message #1: welcome from a real server, no polling involved
// [server] received real message: hello server
// [client] received real message #2: echo: hello server
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 69 of 152 decoded in the Node.js track. One more won't hurt.

Back to track