当用户关闭页面时,如何停止运行服务器发送的事件脚本?的PHP [英] How can i stop a server sent event script from running when the user closes the page? PHP

查看:107
本文介绍了当用户关闭页面时,如何停止运行服务器发送的事件脚本?的PHP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Im trying to use SSE in PHP backend to send messages to a user.

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

the functional part of the backend code looks like-

<?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)不会当用户关闭页面时,什么都不做。

it appears that ignore_user_abort(0) doesn't do anything when the user closes the page.

在$ chatbox-> jsonloadunreadmessages()中,有一个函数只能在页面打开时执行,它会更新在MySQL数据库中。但是即使关闭页面,该脚本仍可在服务器上继续运行!

in $chatbox->jsonloadunreadmessages() there is a function that should only be executed when the page is open, it updates things in mySQL database. but this script keeps on running on the server even when the page is closed!

无论如何,当用户关闭页面以退出页面时,仍可以在服务器端进行检查无限while循环?

is there anyway to check on the server side when the user has closed the page to exit the infinite while loop?

推荐答案

连接套接字关闭后,PHP脚本应该被杀死。如果脚本在用户关闭页面后仍继续运行,则说明Apache / PHP配置存在严重问题。

The PHP script should be killed as soon as the connection socket closes. If the script keeps on running when the user closes the page, there is something very wrong with your Apache/PHP configuration.

当客户端调用<$时,套接字会关闭c $ c> EventSource.close()显然是由于网络问题导致连接丢失,客户端关闭页面或您的PHP脚本终止。

Socket closing can happen when the client calls EventSource.close() explicitely, the connection is lost due to network problems, the client closes the page or your PHP script terminates.

ignore_user_abort(false)不执行任何操作;这是默认行为(关闭连接后脚本会终止)。传递 true 作为参数会使您的脚本在连接中幸存下来,但这不能解决您的问题。

ignore_user_abort(false) does nothing; that's the default behaviour (the script terminates when the connection is closed). Passing true as a parameter would have your script survive the connection, but that would not solve your problem.

您的 retry:1000 没有用,因为您永远不会关闭套接字服务器端。
当客户端激活 EventSource 对象并仅在客户端请求时终止(或者如果网络失败),则应调用PHP脚本,因此无论初始DB怎样调整每个聊天连接只能出现一次。假设客户端没有做任何会关闭连接的操作。

Your retry: 1000 serves no purpose since you're never closing the socket server-side. Your PHP script should be called when the client activates an EventSource object and terminate only at the client's request (or if the network fails), so whatever initial DB tweaking should occur only once per chat connection. That's assuming the client does not do anything that would close the connection.

顺便说一句,这会对服务器造成很大的压力:每个聊天的客户端都有一个PHP进程在整个聊天过程中一直运行,并且轮询时间间隔太小大约10倍(10秒就足够了)。让客户每30秒左右轮询一次新消息,这样就不会浪费很多钱。

Btw this will put a lot of strain to the server: you will have one PHP process per chatting client running for the whole chat duration, and the polling period is about 10 times too small (10 seconds is more than enough). Having the clients poll for new messages every 30 seconds or so would be less wasteful.

这篇关于当用户关闭页面时,如何停止运行服务器发送的事件脚本?的PHP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆