A comparison of WebSockets and Server-Sent Events (SSE) for real-time applications, demonstrated through a PHP-based chat example.
Introduction
When building real-time applications like chat systems, live notifications, or collaborative platforms, developers face a common challenge: how to maintain persistent, low-latency communication between clients and servers. This is where two popular technologies come into play: WebSockets and Server-Sent Events (SSE).
In this blog, we will:
- Compare WebSockets and SSE for real-time communication.
- Provide simple examples of building a chat application using PHP with both technologies.
Let’s dive in!
WebSockets vs Server-Sent Events (SSE)
Before getting into the chat app examples, let’s first break down WebSockets and SSE in terms of their characteristics, strengths, and use cases.
1. What is WebSocket?
WebSocket is a full-duplex communication protocol over a single, long-lived TCP connection. It allows both the client and the server to send and receive messages independently in real-time.
- Protocol: Upgrades an HTTP connection to WebSocket (ws:// or wss://).
- Communication: Bi-directional (client and server can both send data).
- Use Case: Ideal for interactive applications like online games, chat apps, live trading platforms, etc.
- Scalability: Requires careful handling of long-lived connections and often uses message brokers (e.g., Redis, Kafka).
Pros:
- Low latency (bi-directional).
- Persistent connection (faster message delivery after the initial handshake).
- Works well for applications requiring constant updates from both client and server.
Cons:
- Slightly more complex to implement.
- Can consume more server resources (due to many open connections).
- Requires handling reconnections manually.
2. What are Server-Sent Events (SSE)?
SSE is a simpler unidirectional communication protocol over HTTP. It allows the server to send updates to the client (but not vice versa) in real-time.
- Protocol: Uses standard HTTP/HTTPS (with a
Content-Type
oftext/event-stream
). - Communication: One-way (server → client).
- Use Case: Ideal for live notifications or data feeds like stock prices, news updates, or one-way chat messages.
- Scalability: Can be used with a typical HTTP server, though may be less efficient with many clients at once.
Pros:
- Simple to implement using standard HTTP protocols.
- Built-in reconnection mechanism.
- Lightweight (no need for persistent TCP connections).
Cons:
- One-way communication (client cannot send messages).
- Slightly higher latency due to the nature of HTTP.
- Limited browser support (not supported in all mobile browsers, older IE).
When to Use WebSockets vs SSE
Criteria | WebSocket | SSE |
---|---|---|
Bidirectional | ✅ Yes (client ↔ server) | ❌ No (server → client only) |
Latency | ✅ Low (ideal for real-time) | ❌ Slightly higher (due to HTTP) |
Protocol | ✅ WebSocket (TCP-based) | ✅ HTTP/1.1 or HTTP/2 (text/event-stream) |
Scalability | ✅ High (with message brokers) | ❌ Limited at scale (multiple long-lived connections) |
Use Case | ✅ Chat apps, games, live trading | ✅ Notifications, news feeds, alerts |
Server Resources | ❌ Higher (many open connections) | ✅ Lower (uses standard HTTP) |
Complexity | ❌ More complex to implement | ✅ Easier to implement |
Building a Simple Chat Application in PHP: WebSocket vs SSE
Let’s now implement PHP-based chat applications using WebSocket and SSE. We’ll keep things simple, focusing on how each technology works in practice.
1. WebSocket Chat Application in PHP
For WebSockets, we’ll use Ratchet, a PHP WebSocket library, to create a WebSocket server and handle real-time communication.
Steps:
- Install Ratchet and ReactPHP (dependency):
composer require cboden/ratchet
composer require react/event-loop
- Create the WebSocket Server (
chat-server.php
):
<?php
require 'vendor/autoload.php';
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {
public function onOpen(ConnectionInterface $conn) {
echo "New connection: ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg) {
echo "Message from {$from->resourceId}: {$msg}\n";
foreach ($from->httpRequest->getHeaders()['Origin'] as $origin) {
$from->send("Message: $msg");
}
}
public function onClose(ConnectionInterface $conn) {
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo "Error: {$e->getMessage()}\n";
}
}
$server = new Ratchet\App('localhost', 8080);
$server->route('/chat', new Chat, ['*']);
$server->run();
- Create the frontend chat page (
index.html
):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket Chat</title>
</head>
<body>
<h2>WebSocket Chat</h2>
<input id="message" type="text" placeholder="Type your message" />
<button onclick="sendMessage()">Send</button>
<div id="chat"></div>
<script>
const ws = new WebSocket("ws://localhost:8080/chat");
ws.onmessage = function(event) {
const messageDiv = document.createElement("div");
messageDiv.textContent = event.data;
document.getElementById("chat").appendChild(messageDiv);
};
function sendMessage() {
const message = document.getElementById("message").value;
ws.send(message);
}
</script>
</body>
</html>
- Run the WebSocket Server:
php chat-server.php
2. SSE Chat Application in PHP
For SSE, we will use simple HTTP connections to send messages from the server to the client.
Steps:
- Create the SSE endpoint (
sse.php
):
<?php
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");
$redis = new Predis\Client(); // or use other channels
while (true) {
$message = $redis->rpop('chat-messages');
if ($message) {
echo "data: {$message}\n\n";
flush();
}
sleep(1);
}
- Create the message sender (
send.php
):
<?php
if ($_POST['message']) {
$redis = new Predis\Client();
$redis->lpush('chat-messages', $_POST['message']);
echo "Message sent!";
}
- Create the frontend chat page (
index.html
):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSE Chat</title>
</head>
<body>
<h2>SSE Chat</h2>
<div id="messages"></div>
<form id="chatForm">
<input type="text" id="msg" placeholder="Type your message" />
<button type="submit">Send</button>
</form>
<script>
const evtSource = new EventSource("sse.php");
evtSource.onmessage = function(event) {
const p = document.createElement("p");
p.textContent = event.data;
document.getElementById("messages").appendChild(p);
};
document.getElementById("chatForm").addEventListener("submit", async function(e) {
e.preventDefault();
const msg = document.getElementById("msg").value;
await fetch("send.php", {
method: "POST",
body: new URLSearchParams({ message: msg })
});
document.getElementById("msg").value = '';
});
</script>
</body>
</html>
Conclusion
WebSockets are better suited for bidirectional communication in real-time applications like chat systems, where both the client and server need to interact frequently.
On the other hand, Server-Sent Events (SSE) is simpler and works great for one-way data flow from server to client, such as notifications or live feeds, but it lacks the flexibility of WebSockets.
Both WebSockets and SSE can be implemented in PHP, with WebSockets requiring a dedicated server-side WebSocket library (like Ratchet), while SSE can be easily set up using standard PHP HTTP responses.
Which one to choose depends on your application’s needs. If you require high-frequency, bi-directional communication (like chat), WebSockets are the go-to. For simpler, one-way updates (e.g., news feeds), SSE offers a lightweight solution.
Leave a Reply