SSE
Tính năng này yêu cầu workerman>=4.0.0
SSE, hay còn gọi là Server-sent Events, là một công nghệ đẩy từ phía máy chủ. Bản chất của nó là sau khi client gửi một yêu cầu http với header Accept: text/event-stream, kết nối không bị đóng, và máy chủ có thể liên tục gửi dữ liệu đến client qua kết nối này.
Sự khác biệt giữa nó và websocket là:
- SSE chỉ cho phép máy chủ gửi đến client; Websocket có thể giao tiếp hai chiều.
- SSE hỗ trợ tự động kết nối lại khi bị ngắt; WebSocket cần tự triển khai.
- SSE chỉ có thể truyền tải văn bản utf8, dữ liệu nhị phân cần được mã hóa thành utf8 trước khi gửi; WebSocket mặc định hỗ trợ truyền tải cả utf8 và dữ liệu nhị phân.
- SSE có sẵn kiểu tin nhắn; WebSocket cần tự triển khai.
Ví dụ
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\ServerSentEvents;
use Workerman\Protocols\Http\Response;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
// Nếu header Accept là text/event-stream thì đó là yêu cầu SSE
if ($request->header('accept') === 'text/event-stream') {
// Đầu tiên gửi phản hồi với header Content-Type: text/event-stream
$connection->send(new Response(200, ['Content-Type' => 'text/event-stream'], "\r\n"));
// Định kỳ gửi dữ liệu đến client
$timer_id = Timer::add(2, function () use ($connection, &$timer_id){
// Khi kết nối đóng, cần xóa bộ hẹn giờ để tránh bộ hẹn giờ tích lũy gây rò rỉ bộ nhớ
if ($connection->getStatus() !== TcpConnection::STATUS_ESTABLISHED) {
Timer::del($timer_id);
return;
}
// Gửi sự kiện message, dữ liệu sự kiện là hello, id tin nhắn có thể không được truyền
$connection->send(new ServerSentEvents(['event' => 'message', 'data' => 'hello', 'id'=>1]));
});
return;
}
$connection->send('ok');
};
// Chạy worker
Worker::runAll();
Mã javascript phía client
var source = new EventSource('http://127.0.0.1:8080');
source.addEventListener('message', function (event) {
var data = event.data;
console.log(data); // Xuất ra hello
}, false);