SSE
Tính năng này yêu cầu workerman>=4.0.0
SSE hay Server-sent Events, là một công nghệ push từ máy chủ. Bản chất của nó là khi máy khách gửi một yêu cầu HTTP có tiêu đề Accept: text/event-stream
, kết nối không đóng, máy chủ có thể liên tục đẩy dữ liệu đến máy khách thông qua kết nối này.
SSE khác biệt với websocket như sau:
- SSE chỉ cho phép máy chủ đẩy dữ liệu đến máy khách; Websocket có thể trò chuyện hai chiều.
- SSE mặc định hỗ trợ việc kết nối lại khi mất kết nối; Websocket cần phải tự triển khai.
- SSE chỉ có thể truyền dữ liệu văn bản utf8, dữ liệu nhị phân cần phải được mã hóa thành utf8 để truyền; Websocket mặc định hỗ trợ truyền dữ liệu utf8 và nhị phân.
- SSE có loại tin nhắn tích hợp; Websocket cần phải 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 tiêu đề Accept là text/event-stream thì đây là yêu cầu SSE
if ($request->header('accept') === 'text/event-stream') {
// Trước tiên gửi một phản hồi có tiêu đề Content-Type: text/event-stream
$connection->send(new Response(200, ['Content-Type' => 'text/event-stream'], "\r\n"));
// Định kỳ đẩy dữ liệu đến máy khách
$timer_id = Timer::add(2, function () use ($connection, &$timer_id){
// Khi kết nối đóng thì cần xóa định kỳ để tránh tích lũy và gây rò rỉ bộ nhớ
if ($connection->getStatus() !== TcpConnection::STATUS_ESTABLISHED) {
Timer::del($timer_id);
return;
}
// Gửi sự kiện message với dữ liệu là hello, id tin nhắn có thể không cần thiết
$connection->send(new ServerSentEvents(['event' => 'message', 'data' => 'hello', 'id'=>1]));
});
return;
}
$connection->send('ok');
};
// Chạy worker
Worker::runAll();
Mã JavaScript trên máy khách
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);