服务器发送事件轮询导致长时间延迟

我有一个连接器,它将使用cURL和PHP调用RESP API。

我需要每秒调用一个方法来检查新消息然后处理它们。 我使用以下两种方法来处理消息

  1. 使用SetInterval() AJAX轮询:每秒调用一次php脚本。 除非我无法防止多个SetInterval()从浏览器的不同选项卡同时运行,否则这种方法很有效。 (我不想让用户打开10个浏览器选项卡,这导致一个用户有10个SetInterval()同时运行。
  2. 使用EventSource服务器发送事件:一旦队列中有新数据,服务器将发送更新浏览器。 这会减慢响应时间。 我对脚本的每次调用都需要大约20秒才能完成,这是一个问题。 我不确定为什么会这样。

这是我的SetInterval()实现

 function startCalls(){ //update the screen using Intervals refreshIntervalId = setInterval(function() { $.getJSON("index.php", {'method': 'getMessages', 'jSON': true} , function(data){ processServerData(data); }); }, 1000); } 

一旦用户登录我就调用了这个函数startCalls()

在index.php文件中我有这个代码要调用

 if($method == 'getMessages'){ $messaging = new ICWS\Messaging($icws); $messaging->processMessages(); $myQueue = $messaging->getCallsQueue(); echo json_encode($myQueue ); } 

这是我的第二个实现“Server-Sent Events”

 //Server Side Message Polling function startPolling(evtSource){ evtSource.addEventListener("getMessagingQueue", function(e) { var data = JSON.parse(e.data); processServerData(data) }, false); } 

一旦用户登录,我就调用这个函数startPolling( new EventSource("poll.php") );

为简单起见,假设我的processServerData方法如下所示

 function processServerData(data){ console.log('process the data received from the server'); } 

这是我的PHP代码

  '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(); } ?> 

服务器似乎锁定所有命中服务器的请求,直到我刷新页面时“页面刷新”停止无限循环,其他请求立即进行处理

为什么Server-Sent Event会导致这样的问题?

本课题可以找到不同类型的极化的重要资源

一切看起来都很健壮,所以我会猜测你被会话锁定所打击。 PHP会话锁定会话文件,这样一次只有一个PHP脚本可以使用该会话; 当你想到它时,这是一个好主意!

会话和SSE的问题在于SSE PHP进程永远运行,因此会永久锁定会话。 如果任何其他PHP脚本尝试使用相同的会话运行,它将阻止(在session_start()调用,我相信)。

这看起来像是关于这个主题的好文章 ; 一旦你知道更长时间需要会话,建议是调用session_write_close() 。 例如,如果您只需要使用会话来检查他们之前是否已经授权,那么在您调用session_write_close() ,其他进程将不会被阻止。

Interesting Posts