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

时间:2015-03-04 09:37:04

标签: php comet server-sent-events

我试图在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);

    }
?>
&#13;
&#13;
&#13;

当用户关闭页面时,似乎ignore_user_abort(0)没有做任何事情。

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

无论如何,当用户关闭页面以退出无限循环时,是否还要检查服务器端?

2 个答案:

答案 0 :(得分:1)

连接套接字关闭后,应立即终止PHP脚本。如果脚本在用户关闭页面时继续运行,那么Apache / PHP配置就会出现问题。

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

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

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

顺便说一下,这会给服务器带来很大压力:每个聊天客户端都会有一个PHP进程在整个聊天时间内运行,并且轮询周期大约是10倍(10秒就足够了)。每隔30秒左右让客户轮询新邮件就不那么浪费了。

答案 1 :(得分:0)

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

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

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