欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

javascript - h5有个Server-sent Events,php端该怎么写?

程序员文章站 2022-05-11 17:43:28
...

public static function pushEvent(){
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache'); // 建议不要缓存SSE数据
    header('Connection: keep-alive');
    //header('X-Accel-Buffering: no');//有可能用nginx的需要设置这个才能把缓冲数据刷出去

    $serverTime = time();
    $hasData = hFile::cache('pushEvent');//读缓存
    if($hasData){
        hFile::cache('pushEvent',0);//存缓存
        self::sendMsg($serverTime, 'server time: ' . date("h:i:s"),'myevent',100000);
    }else
        self::sendMsg('','','',100);//多少毫秒内无数据,再重连
}


/**
 * @param string $id Timestamp/id of this connection.
 * @param string $msg Line of text that should be transmitted.
 * @param $event string
 */
private static function sendMsg($id='', $msg='',$event='',$retry=''){
    if(!($id||$event||$msg||$retry))
        return;

    if($retry) echo "retry: $retry" .PHP_EOL;
    if($id) echo "id: $id" . PHP_EOL;
    if($event) echo "event: {$event}" . PHP_EOL;
    if($msg) echo "data: $msg" . PHP_EOL;
    echo PHP_EOL;//表示本条数据结束
    ob_flush();
    flush();
}

我是上面这样写的,(部分代码是抄来的)。问题是,前端每建立一次连接,php只能返回一次数据,如果想要下一次的数据,是靠这行self::sendMsg('','','',100);//多少毫秒内无数据,再重连,这行会让前端多少毫秒后再重新建立连接,这样觉得会非常浪费资源,而且每次要输出数据前是读取缓存是否有发给该用户的消息这种方式,还有没有别的好方式?

回复内容:


public static function pushEvent(){
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache'); // 建议不要缓存SSE数据
    header('Connection: keep-alive');
    //header('X-Accel-Buffering: no');//有可能用nginx的需要设置这个才能把缓冲数据刷出去

    $serverTime = time();
    $hasData = hFile::cache('pushEvent');//读缓存
    if($hasData){
        hFile::cache('pushEvent',0);//存缓存
        self::sendMsg($serverTime, 'server time: ' . date("h:i:s"),'myevent',100000);
    }else
        self::sendMsg('','','',100);//多少毫秒内无数据,再重连
}


/**
 * @param string $id Timestamp/id of this connection.
 * @param string $msg Line of text that should be transmitted.
 * @param $event string
 */
private static function sendMsg($id='', $msg='',$event='',$retry=''){
    if(!($id||$event||$msg||$retry))
        return;

    if($retry) echo "retry: $retry" .PHP_EOL;
    if($id) echo "id: $id" . PHP_EOL;
    if($event) echo "event: {$event}" . PHP_EOL;
    if($msg) echo "data: $msg" . PHP_EOL;
    echo PHP_EOL;//表示本条数据结束
    ob_flush();
    flush();
}

我是上面这样写的,(部分代码是抄来的)。问题是,前端每建立一次连接,php只能返回一次数据,如果想要下一次的数据,是靠这行self::sendMsg('','','',100);//多少毫秒内无数据,再重连,这行会让前端多少毫秒后再重新建立连接,这样觉得会非常浪费资源,而且每次要输出数据前是读取缓存是否有发给该用户的消息这种方式,还有没有别的好方式?

请参考我的这篇文章: https://segmentfault.com/a/11...

最关键的是下面这段:

ob_flush();
flush();
//等待3秒钟,开始下一次查询
sleep(3);

flush之后,不要断开连接,而是睡眠3秒后再次进入循环,这样就可以保持住连接,不会断开重连。

为什么不通过websocket去做这样的事呢?