问题
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