WebSockets & real-time connections

Key takeaways Plain HTTP is one-shot request/response: the client asks, the server answers, and the exchange is over. That’s perfect for loading a page, but live apps need the server to tell you the moment something changes. A WebSocket solves this by opening a persistent connection — a single long-lived channel where either side can send messages at any time, so the server can push data without waiting to be asked.

Almost everything you’ve learned so far assumes the client asks and the server answers. That model built the web, but it has one blind spot: the server can never speak first. Real-time apps — chat, live dashboards, streaming — need exactly that, and this lesson is about how they get it.

The limit of request/response

In the client-server model, the HTTP exchange only ever runs in one direction to begin with: the client always has to ask. The server sits and waits, and no matter how much has changed on its end, it cannot reach out to tell you. It can only answer a request you’ve already sent.

That’s fine when you’re fetching a page or submitting a form — you ask, you get an answer, you’re done. But imagine a chat app built this way. New messages arrive on the server, but your browser has no idea until it asks. So it asks again. And again. This is polling: repeatedly firing off requests — “anything new? anything new?” — just in case.

Polling works, but it’s wasteful. Poll too slowly and updates feel laggy; poll too quickly and you flood the server with mostly-empty requests. The real problem is structural: request/response gives the server no way to speak first. To build something genuinely live, we need a channel the server can talk over whenever it likes.

WebSockets

A WebSocket is that channel. It’s a persistent, full-duplex connection — “full-duplex” just meaning both sides can send at the same time, like a phone call rather than a walkie-talkie.

The clever part is how it starts. A WebSocket begins life as an ordinary HTTP request carrying a special header that asks to upgrade the connection. If the server agrees, the two sides stop speaking HTTP and keep the very same connection open as a WebSocket. From that moment on, there’s no more asking and answering — either side can send a message any time, for as long as the connection lives.

That changes what’s possible. The server can push a new chat message the instant it arrives, update a dashboard the moment a number moves, or stream a continuous feed of events — all without the client polling for any of it. Chat, live dashboards, multiplayer games, notifications, and streaming are the classic cases, and they all share the same shape: data that arrives unpredictably and needs to reach the user right away.

Simpler alternatives

A full two-way WebSocket is more than some apps need. Two lighter options cover common cases.

Server-Sent Events (SSE) open a one-way stream from server to client over an ordinary HTTP connection. The client makes a single request, and the server keeps the response open, sending updates down it as they happen. There’s no channel back — the client still uses normal HTTP requests to send anything — but when only the server needs to push (a news ticker, a progress feed, a notifications stream), SSE gives you that with far less machinery than a WebSocket.

Long polling is simpler still, and older. The client makes a request, but instead of answering immediately, the server holds it open until it actually has something to say. When news arrives, the server responds; the client reads it and immediately opens another request to wait again. It approximates a live feed using nothing but standard requests, which makes it a reliable fallback where WebSockets or SSE aren’t available — at the cost of the overhead of constantly reopening connections.

The rule of thumb: reach for long polling only as a fallback, SSE when the push is one-way, and a WebSocket when both sides need to talk freely.

Trade-offs

Real-time connections aren’t free. A persistent connection stays open, so the server holds resources for every connected client whether or not anything is being sent — thousands of idle WebSockets still cost thousands of open connections.

They also need reconnection handling. Networks drop, laptops sleep, phones switch from Wi-Fi to cellular — and unlike a one-shot request you can simply retry, a dropped persistent connection has to be detected and re-established, often while catching up on whatever was missed.

And they interact awkwardly with the infrastructure in between. Proxies and load balancers, firewalls, and timeouts are mostly tuned for short HTTP requests, and a connection that stays open for hours can trip them up unless everything along the path is configured to allow it.

None of this is a reason to avoid WebSockets — it’s a reason to spend them deliberately. Keep persistent connections for genuinely live needs, and let plain request/response handle everything that can wait to be asked.

Where GopherTrunk fits

A scanner is a live thing — calls come and go second by second — and a web interface that reflects that is a textbook real-time connection. When GopherTrunk’s interface shows call activity appearing the instant it happens, or streams decoded audio to your browser, it isn’t polling for updates: the server is pushing them over an open channel, exactly the pattern this lesson describes. We’ll see how that fits into the wider picture of putting the scanner on your network in GopherTrunk on the network.

Quick check: what does a WebSocket give you that plain HTTP request/response doesn't?

Recap

  • Plain HTTP is one-shot request/response: the client always asks, and the server can never speak first.
  • Faking live updates by polling — asking over and over — is wasteful and laggy.
  • A WebSocket opens a persistent, two-way channel by upgrading an HTTP connection; afterwards either side can send messages any time.
  • Server-Sent Events give a one-way server-to-client stream, and long polling approximates live updates with held-open requests — simpler when that’s all you need.
  • Persistent connections cost resources, need reconnection handling, and can clash with proxies and firewalls — so keep them for genuinely real-time needs.
  • GopherTrunk pushing live call activity or streaming audio to your browser is exactly this kind of real-time connection.

Next up: Module 4 covers connecting and securing networks — firewalls & controlling access