Real-Time PHP with WebSockets

WebSockets keep a single connection open so your server can push updates to clients the instant they happen — no polling. In this final lesson you'll see the protocol vs HTTP, build a server with Ratchet , broadcast events with Laravel Reverb and Echo , and use the publish/subscribe pattern for chat and live updates.

Learn Real-Time PHP with WebSockets in our free PHP course — an interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ The Problem: HTTP Polling

HTTP is request/response : the client asks, the server answers, the connection closes. To fake real-time updates, apps resort to polling — re-requesting on a timer to ask "anything new?". The trouble is that most of those requests come back empty, wasting bandwidth and server work, and there's always a gap (up to the polling interval) between an event happening and the user seeing it. For chat or live data, that's both inefficient and noticeably laggy.

The fundamental limit is that the server can't speak first over plain HTTP — it can only answer when asked. WebSockets remove exactly that limit.

2️⃣ The WebSocket Handshake

A WebSocket starts as an ordinary HTTP request carrying an Upgrade: websocket header. If the server agrees, it replies 101 Switching Protocols and the connection switches from HTTP to the persistent WebSocket protocol. From that point the socket stays open and full-duplex : either side can send a message at any time until someone closes it. Use ws:// for plain and wss:// for TLS-encrypted connections.

Because it begins as HTTP, a WebSocket travels over the same ports (80/443) and through the same proxies as normal web traffic — it just refuses to hang up afterward.

3️⃣ A WebSocket Server with Ratchet

In classic PHP, Ratchet ( composer require cboden/ratchet ) lets you build a WebSocket server. You implement four lifecycle hooks — onOpen , onMessage , onClose , onError — and keep the set of connected clients in memory. The crucial difference from normal PHP is that this is a long-running process : you start it once with php server.php and it stays alive holding every socket, rather than running one request and exiting like PHP-FPM.

The onMessage hook here broadcasts — it loops over the stored clients and pushes the message to each one. That's publish/subscribe in miniature: one sender, many receivers, no polling.

4️⃣ The Browser Client

PHP runs the server; the browser opens the connection. The native WebSocket object connects to your wss:// URL and exposes event handlers: onopen , onmessage , and onclose . The key one is onmessage — it fires the instant the server pushes data, with no timer and no polling, which is the whole point.

Send with socket.send() and receive in onmessage — a clean, symmetric, two-way channel between browser and PHP server.

5️⃣ Broadcasting with Laravel Reverb & Echo

In Laravel, you rarely write socket plumbing by hand. Reverb is Laravel's first-party WebSocket server ( php artisan install:broadcasting , then php artisan reverb:start ), and Echo is the matching browser client. You define an event that implements ShouldBroadcast and declares the channel it broadcasts on; firing that event pushes it to every subscriber in real time. This is the publish/subscribe model wired straight into the framework.

Now you try the two core skills — broadcasting an event and opening a client socket. Fill in each ___ using the 👉 hint, then check it against the Output panel.

One more. Open a socket in the browser and react to pushed messages — no polling.

📋 Quick Reference — Real-Time PHP

No code is filled in this time — just a brief and an outline. Build a real-time feed with either Ratchet or Laravel Reverb: run a long-lived server, broadcast events to subscribers, and render each pushed message live in the browser. This is the publish/subscribe loop behind every chat and notifications system.

Practice quiz

What is the key advantage of WebSockets over HTTP polling?

  • They keep one persistent, two-way connection open so the server can push data instantly
  • They require no server at all
  • They encrypt data that HTTP cannot
  • They use less memory on the client

Answer: They keep one persistent, two-way connection open so the server can push data instantly. A WebSocket holds a single long-lived, full-duplex connection, so the server can push messages the moment something happens, instead of the client repeatedly asking.

Why is HTTP polling inefficient for real-time updates?

  • It cannot send JSON
  • It only works over HTTPS
  • The client must repeatedly request, wasting requests when nothing has changed
  • It blocks the database

Answer: The client must repeatedly request, wasting requests when nothing has changed. Polling re-requests on a timer whether or not there is new data, creating wasted round trips and latency between an event and the client learning about it.

How does a WebSocket connection begin?

  • With a database transaction
  • With an HTTP request that is upgraded to the WebSocket protocol
  • With a raw TCP packet only
  • With an FTP handshake

Answer: With an HTTP request that is upgraded to the WebSocket protocol. The client sends an HTTP request containing an Upgrade: websocket header; if the server agrees, the connection switches to the ws:// (or wss://) protocol.

Which classic PHP library lets you build a WebSocket server?

  • Twig
  • Carbon
  • PHPUnit
  • Ratchet

Answer: Ratchet. Ratchet is a long-standing PHP library for building WebSocket servers on top of an event loop (ReactPHP).

What does Laravel Reverb provide?

  • A first-party WebSocket server for Laravel broadcasting
  • A CSS framework
  • A templating engine
  • A database migration tool

Answer: A first-party WebSocket server for Laravel broadcasting. Reverb is Laravel's official, self-hosted WebSocket server that powers real-time broadcasting; the client side is handled by Laravel Echo.

In the publish/subscribe pattern, what does a client do to receive messages about a topic?

  • Polls the database directly
  • Subscribes to a channel and receives every event published to it
  • Opens a new connection per message
  • Sends an email

Answer: Subscribes to a channel and receives every event published to it. Clients subscribe to named channels; when the server publishes an event to a channel, every subscriber receives it without asking.

Why can't a standard request-per-request PHP setup hold WebSocket connections by default?

  • WebSockets require Python
  • PHP cannot parse JSON
  • PHP has no networking functions
  • The usual model starts a process, handles one request, and exits - it isn't a long-running server

Answer: The usual model starts a process, handles one request, and exits - it isn't a long-running server. Classic PHP (via PHP-FPM) is request-per-request: a script runs and exits. WebSockets need a persistent, long-running process with an event loop to keep sockets open.

In Laravel, how do you push a real-time update to subscribed clients?

  • Run a database migration
  • Echo it to standard output
  • Broadcast an event that implements ShouldBroadcast
  • Write it to a log file

Answer: Broadcast an event that implements ShouldBroadcast. You fire a Laravel event that implements ShouldBroadcast; the broadcasting system sends it over the WebSocket server to clients subscribed to its channel.

Which use case is the best fit for WebSockets?

  • A one-time file download
  • A live chat application with instant message delivery
  • Generating a static PDF
  • A nightly batch report

Answer: A live chat application with instant message delivery. Chat, live dashboards, notifications, and multiplayer features all need instant, bidirectional updates - exactly what persistent WebSocket connections provide.

What is the correct URL scheme for an encrypted WebSocket connection?

  • wss://
  • https://
  • ftp://
  • ws://

Answer: wss://. ws:// is a plain WebSocket connection; wss:// is the TLS-encrypted version, the WebSocket equivalent of HTTPS.