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

寵の児 提交于 2019-12-13 01:55:11

问题


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

    }
?>

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

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!

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


回答1:


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.

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) 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.

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.

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.




回答2:


ignore_user_abort() is ignored on IIS Systems and may be prevented by your configuration.

Try to use connection_aborted() in your while loop:

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


来源:https://stackoverflow.com/questions/28850986/how-can-i-stop-a-server-sent-event-script-from-running-when-the-user-closes-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!