I have a connector that will call a RESP API using cURL and PHP.
I need to call one method every second to check for new messages and then process them. I used the following 2 approaches to handle the messages
- AJAX Polling using
SetInterval()
: call the php script once every second. This works perfectly except I am unable to prevent multipleSetInterval()
from running at the same time from different tabs of the browser. ( I don't want to have user opens 10 browser tabs which leads to one user having 10SetInterval()
are running at the same time. - Server Sent Events using
EventSource
: The server will send update the browser once there are new data in the queue. This slows down the respond time. Every call I make to the script takes about 20+ seconds to complete which is a problem. I am not sure why this is happening.
Here is my SetInterval()
implementation
function startCalls(){
//update the screen using Intervals
refreshIntervalId = setInterval(function() {
$.getJSON("index.php", {'method': 'getMessages', 'jSON': true} , function(data){
processServerData(data);
});
}, 1000);
}
once a user logs in I calls this function startCalls()
inside the index.php file I have this code to be called
if($method == 'getMessages'){
$messaging = new ICWS\Messaging($icws);
$messaging->processMessages();
$myQueue = $messaging->getCallsQueue();
echo json_encode($myQueue );
}
Here is my second implementation "Server-Sent Events"
//Server Side Message Polling
function startPolling(evtSource){
evtSource.addEventListener("getMessagingQueue", function(e) {
var data = JSON.parse(e.data);
processServerData(data)
}, false);
}
once a user logs in I calls this function startPolling( new EventSource("poll.php") );
For the sake of simplicity, assume that my processServerData
method looks like this
function processServerData(data){
console.log('process the data received from the server');
}
here is my php code
<?php
require 'autoloader.php';
//Make sure cURL is enabled on the server
if(!is_callable('curl_init')){
exit('cURL is disabled on this server. Before making API calls cURL extension must be enabled.');
}
if( isset($_COOKIE['icws_username']) ){
$user = trim($_COOKIE['icws_username']);
}
if( isset($_COOKIE['icws_password']) ){
$pass = trim($_COOKIE['icws_password']);
}
if( isset($_COOKIE['icws_station']) ){
$stationName = trim($_COOKIE['icws_station']);
}
if( !isset($user, $pass, $stationName) ){
echo json_encode(array('status' => 'The IC credentials you entered are invalid'));
exit;
}
$scheme = 'http';
$host = 'host';
$port = '8018';
$sleepTime = 1;
$url = sprintf('%s://%s:%s@%s:%s', $scheme, $user, $pass, $host, $port);
try {
header("Content-Type: text/event-stream\n\n");
session_start();
//configure the connection
$conf = new ICWS\Config\Config($url, $stationName);
//create a new instance of icws
$attrebutes = array();
$icws = new ICWS\Connection($conf, $attrebutes, true);
$messaging = new ICWS\Messaging($icws);
ob_end_clean();
while(true){
header("Content-Type: text/event-stream" . PHP_EOL);
header("Cache-Control: no-cache" . PHP_EOL);
$messaging->processMessages();
$result = $messaging->getCallsQueue();
//$current = $icws->getCurrentUserStatusQueue();
echo 'event: getMessagingQueue' . PHP_EOL;
echo 'data: ' . json_encode( $result) . PHP_EOL;
echo PHP_EOL; //required
ob_end_flush();
flush();
sleep(1);
}
} catch(Exception $e){
echo $e->getMessage();
}
?>
The server seems to lock all requests that hit the server until the infinite loop is stopped by "page refresh" as soon as I refresh the page the other requests are processes immediately
Why would the Server-Sent Event cause such an issue?
A great resource for the different types of poling can be found in this Question