Mastering Server‑Sent Events (SSE) in PHP & JavaScript: Real‑Time Push Guide

This article explains Server‑Sent Events (SSE), a one‑way HTTP‑based real‑time push technology, and provides detailed server‑side PHP and client‑side JavaScript examples, required headers, message formatting rules, and typical use‑case scenarios for low‑overhead streaming.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Mastering Server‑Sent Events (SSE) in PHP & JavaScript: Real‑Time Push Guide

Introduction

SSE (Server‑Sent Events) enables the server to push real‑time data to the client over a persistent HTTP connection. Unlike WebSocket, SSE is strictly one‑way (server → client), automatically reconnects, uses the simple EventSource API, and has low implementation cost, making it ideal for notifications, log streams, and other push‑only scenarios.

Server and Client Architecture

The core of SSE is a long‑lived HTTP connection that returns text/event-stream content encoded in UTF‑8. For example, ChatGPT streams its answer token‑by‑token using SSE, allowing the client to receive partial results without waiting for the entire response.

Key Features

Single‑direction communication : only server‑to‑client data flow; client cannot send data via SSE.

Long connection : a single connection stays open, avoiding repeated handshakes.

Automatic reconnection : the client retries automatically (default 3 seconds) when the connection drops.

Text stream : data is sent as UTF‑8 text; binary data must be encoded.

Code Example – Server (PHP)

<?php
/**
 * @desc Controller using SSE
 * @author Tinywan (ShaoBo Wan)
 */
declare(strict_types=1);

namespace app\controller;

use support\Request;
use support\Response;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\ServerSentEvents;
use Workerman\Timer;

class StreamController
{
    /**
     * @desc client page
     * @param Request $request
     * @return Response
     */
    public function client(Request $request): Response
    {
        return view('stream/client', ['name' => '开源技术小栈']);
    }

    /**
     * @desc server SSE endpoint
     * @param Request $request
     * @return Response
     */
    public function server(Request $request): Response
    {
        $connection = $request->connection;
        $id = Timer::add(1, function () use ($connection, &$id) {
            if ($connection->getStatus() !== TcpConnection::STATUS_ESTABLISHED) {
                Timer::del($id);
            }
            $connection->send(new ServerSentEvents([
                'event' => 'message',
                'data'  => date('Y-m-d H:i:s') . ' 服务端发送数据',
                'id'    => 2026
            ]));
        });
        $header = [
            'Content-Type'  => 'text/event-stream',
            'Cache-Control' => 'no-cache',
            'Connection'    => 'keep-alive',
        ];
        return response('', 200, $header);
    }
}

Required HTTP Response Headers

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

Optional Header (recommended for Nginx)

X-Accel-Buffering: no

SSE Message Format

Each SSE message consists of one or more fields, each on its own line, terminated by a blank line ( \n\n). The most important fields are: data: required – the payload of the message. event: optional – custom event name (default is message). id: recommended – unique identifier for reconnection. retry: optional – reconnection delay in milliseconds. : – comment line, ignored by the client, useful for heart‑beats.

Client Implementation (JavaScript)

// Create an SSE connection (GET only)
const sse = new EventSource('/service/stream');

sse.onmessage = function (e) {
    output.textContent += e.data + '
';
    output.scrollTop = output.scrollHeight;
};

sse.onopen = function () {
    output.textContent = '';
};

The browser automatically sends Accept: text/event-stream and keeps the connection alive. The client can also listen for custom events using addEventListener('eventName', handler).

Typical Use Cases

AI assistants / large‑model streaming (e.g., ChatGPT token‑by‑token output).

Real‑time notifications such as comments, likes, private messages, or system alerts.

Task execution logs and progress bars for backend jobs (model training, CI/CD pipelines, file processing).

Live news feeds, content recommendation streams.

Financial market tickers for stocks, crypto, or forex.

Server and application monitoring dashboards (CPU, memory, QPS, error rates).

Collaborative editing status synchronization (cursor position, edit presence).

Live sports scores, event updates, or real‑time location tracking for delivery services.

Business Characteristics Suited for SSE

Data flow direction: server → client (push‑only).

Update frequency: low to medium (event‑driven or every few seconds).

Payload size: small (bytes to a few KB of text/JSON).

Connection duration: minutes to hours.

Reliability: moderate (occasional loss acceptable).

Development complexity: prefers simpler HTTP‑based solution over full WebSocket.

real-timeJavaScriptWeb developmentserver-sent-eventsSSE
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.