eventSource调用close关闭后会触发服务端的连接关闭事件,我们以swoole为例来看看:
<?php use Swoole\Http\Request; use Swoole\Http\Response; // 设置响应头 function setHeader(Response $response) { $response->header('Content-Type', 'text/event-stream'); $response->header('Cache-Control', 'no-cache'); $response->header('Connection', 'keep-alive'); } // 发送事件 function sendEvent(Response $response, $event, $data) { $response->write("event:$event\n"); $response->write("data:$data\n\n"); } // 用于存储定时器ID的数组 $timerIds = []; // 创建HTTP服务器 $server = new Swoole\Http\Server('0.0.0.0', 9502); // 处理请求 $server->on('request', function(Request $request, Response $response) use(&$timerIds) { if ($request->server['request_uri'] == '/html') { // 返回一个文件上传表单 $response->end(' <script type="text/javascript"> const data = new EventSource("/test"); data.onmessage = function(event) { document.body.innerHTML += event.data + \'<br>\'; }; setTimeout(function(){ data.close(); },5000); </script> '); } else { setHeader($response); $fd = $request->fd; // 发送初始化事件 sendEvent($response, 'init', 'Hello World'); global $timerIds; $timerIds[$fd] = swoole_timer_tick(1000, function () use ($response, $fd) { // if ($response->isWritable()) { $data = [ 'time' => date('H:i:s'), 'message' => 'Hello, world!', ]; $response->write('data: ' . json_encode($data) . "\n\n"); // } else { // 如果连接不可写,则停止定时器 // swoole_timer_clear($timerIds[$fd]); // unset($timerIds[$fd]); //} }); } }); // 在连接关闭时清除定时器 $server->on('close', function ($server, $fd) use (&$timerIds) { echo "Client {$fd} closed\n"; global $timerIds; if (isset($timerIds[$fd])) { swoole_timer_clear($timerIds[$fd]); unset($timerIds[$fd]); } }); // 启动服务器 $server->start();
网友回复