当用户关闭页面时,如何停止服务器从 运行 发送的事件脚本? PHP

How can i stop a server sent event script from running when the user closes the page? PHP

我正在尝试在 PHP 后端中使用 SSE 向用户发送消息。

后端代码的功能部分看起来像-

<?php
set_time_limit(0);
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
ignore_user_abort(0);
@session_start();
    ob_start();
    echo "retry: 1000\n";

    ob_flush();
    flush();

    require_once 'sql_connection_class.php';
    require 'chatbox_class.php';

    $chatbox=new chatboxclass($_GET['friendid']);

    function recursivesenddata(){
    global $chatbox;
    $jsonobj=$chatbox->jsonloadunreadmessages();

    //append json object


if($jsonobj!=-1){

>           echo "data:{$jsonobj}\n\n";
>           ob_flush();
>           flush();
>         }else{
>           //don't send anything   
>         }
    }



while(true){
      recursivesenddata();
      session_write_close();
      sleep(1);

    }
?>

当用户关闭页面时,ignore_user_abort(0) 似乎没有执行任何操作。

在 $chatbox->jsonloadunreadmessages() 中有一个函数只应在页面打开时执行,它会更新 mySQL 数据库中的内容。但是即使页面关闭,这个脚本仍然在服务器上 运行!

当用户关闭页面以退出无限 while 循环时,是否要在服务器端进行检查?

ignore_user_abort() 在 IIS 系统上被忽略,您的配置可能会阻止它。

尝试在 while 循环中使用 connection_aborted():

while ( connection_aborted() == 0 ) {
    recursivesenddata();
    session_write_close();
    sleep(1);
}

PHP 脚本应该在连接套接字关闭后立即终止。如果脚本在用户关闭页面时保持 运行,则您的 Apache/PHP 配置有问题。

当客户端显式调用 EventSource.close()、由于网络问题导致连接丢失、客户端关闭页面或您的 PHP 脚本终止时,可能会发生套接字关闭。

ignore_user_abort(false) 什么都不做;这是默认行为(脚本在连接关闭时终止)。将 true 作为参数传递会使您的脚本在连接后继续存在,但这不会解决您的问题。

您的 retry: 1000 没有任何用处,因为您永远不会关闭套接字服务器端。 您的 PHP 脚本应在客户端激活 EventSource 对象时调用,并且仅在客户端请求时(或网络出现故障时)终止,因此无论初始数据库调整如何,每个聊天连接都应仅发生一次。这是假设客户端没有做任何会关闭连接的事情。

顺便说一句,这会给服务器带来很大的压力:在整个聊天期间,每个聊天客户端 运行 将有一个 PHP 进程,轮询周期也是大约 10 次小(10 秒绰绰有余)。让客户端每 30 秒左右轮询一次新消息会减少浪费。