+
95
-

回答

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();

网友回复

我知道答案,我要回答