Reputation: 1985
I'm thinking about migrating my notification system which uses ajax pooling to server sent events in a way similar to:
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
$sql = "SELECT name,body FROM notification where id='user1'";
...
echo 'data: ' . json_encode($arrayResult) . "\n\n";
$conn->close();
flush();
?>
My question though is that this seems to be constantly making queries to the DB (in similar way to ajax pooling) which seems can become quite intensive.
What would you suggest to alter on the server side code so that it's not constantly pooling the database but would only query it after a notification was inserted?
Upvotes: 0
Views: 1325
Reputation: 40896
What's happening is that by default, the browser will reopen the connection after 3 seconds and your script will run once more and query the DB. Another problem I see is that your sql query will always return results even if there is no new notification since the last check. A better query would select only recent notification. You have three simple options
retry
parameterBy sending the browser a retry
value with the first message, you control how long the browser will wait to reopen the connection:
echo "retry: 60000\n"; // reopen the connection in 60 seconds
echo 'data: ' . json_encode($arrayResult) . "\n\n";
Instead of letting your script quickly execute to the end and having the browser reopen the connection 3 seconds later, you can do your DB check in a loop whose frequency you control
set_time_limit(0); // remove any time limit to script execution
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header("Connection: keep-alive");
while(true){
$sql = 'SELECT...'; // alter your query to only fetch recent notifications
// fetch results and put in $arrayResult
if(!empty($arrayResult)) echo 'data: ' . json_encode($arrayResult) . "\n\n";
ob_flush(); flush();
sleep(60); // sleep for 60 seconds
}
A memory cache can store notifications in one script execution and retrieve them in the other. So your script would:
I've used memcache but there are others. This does require you to install new software on the web server, but it's probably what I would do.
Upvotes: 2
Reputation: 1536
In that case you would need to intercept the notification directly in the code that inserts it in the database (thus short-circuiting the database).
A more conventional way of doing this would be to use a message broker.
Upvotes: 0