Server-Sent Events (SSE) Trong Laravel: Giải Pháp Thay Thế Đơn Giản Cho WebSockets
·
2 min read
WebSockets (Reverb/Pusher) là hai chiều. Client nói chuyện với server, và server nói chuyện với client. Điều này tuyệt vời cho chat.
Nhưng nếu bạn chỉ muốn cập nhật "Giá Cổ Phiếu" hoặc "Progress Bar" thì sao? Bạn chỉ cần server nói chuyện với client.
Server-Sent Events (SSE) là một công nghệ HTTP tiêu chuẩn giữ kết nối mở và stream dữ liệu text.
Tại Sao SSE?
- Đơn giản hơn: Hoạt động trên HTTP tiêu chuẩn. Không cần protocol đặc biệt (ws://).
- Thân thiện với firewall: Nó chỉ là một request bình thường.
- Tự động kết nối lại: Trình duyệt xử lý retries tự động.
Triển Khai Trong Laravel
Chúng ta sử dụng StreamedResponse.
public function stream()
{
return response()->stream(function () {
while (true) {
$data = [
'time' => now()->toTimeString(),
'stock' => rand(100, 200)
];
echo "data: " . json_encode($data) . "\n\n";
if (ob_get_level() > 0) {
ob_flush();
}
flush();
if (connection_aborted()) {
break;
}
sleep(1); // Gửi cập nhật mỗi giây
}
}, 200, [
'Content-Type' => 'text/event-stream',
'Cache-Control' => 'no-cache',
'Connection' => 'keep-alive',
]);
}
Frontend Client
JavaScript có API EventSource native. Không cần thư viện!
const source = new EventSource('/stream');
source.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log("Stock Price:", data.stock);
};
Các Lưu Ý
- PHP Workers: Mỗi kết nối SSE giữ một PHP-FPM worker mở. Nếu bạn có 100 người dùng, bạn cần 100 workers. Kiến trúc này không tốt cho PHP-FPM.
- Giải pháp: Sử dụng Laravel Octane (Swoole/RoadRunner) xử lý các kết nối đồng thời một cách bất đồng bộ mà không blocking threads.
Với admin dashboards lưu lượng thấp, PHP tiêu chuẩn là đủ. Để scale cao, hãy sử dụng WebSockets hoặc Octane.