Jay*_*len 5 javascript php jquery server-sent-events icws
我有一个连接器,它将使用 cURL 和 PHP 调用 RESP API。
我需要每秒调用一个方法来检查新消息,然后处理它们。我使用以下两种方法来处理消息
SetInterval()
:每秒调用一次 php 脚本。这工作得很好,除了我无法阻止多个SetInterval()
浏览器的不同选项卡同时运行。(我不想让用户打开 10 个浏览器选项卡,这会导致一个用户SetInterval()
同时运行 10 个浏览器选项卡。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);
}
Run Code Online (Sandbox Code Playgroud)
一旦用户登录,我就会调用此函数startCalls()
在 index.php 文件内我有要调用的代码
if($method == 'getMessages'){
$messaging = new ICWS\Messaging($icws);
$messaging->processMessages();
$myQueue = $messaging->getCallsQueue();
echo json_encode($myQueue );
}
Run Code Online (Sandbox Code Playgroud)
这是我的第二个实现“服务器发送事件”
//Server Side Message Polling
function startPolling(evtSource){
evtSource.addEventListener("getMessagingQueue", function(e) {
var data = JSON.parse(e.data);
processServerData(data)
}, false);
}
Run Code Online (Sandbox Code Playgroud)
一旦用户登录,我就会调用此函数startPolling( new EventSource("poll.php") );
为了简单起见,假设我的processServerData
方法如下所示
function processServerData(data){
console.log('process the data received from the server');
}
Run Code Online (Sandbox Code Playgroud)
这是我的 php 代码
<?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();
}
?>
Run Code Online (Sandbox Code Playgroud)
服务器似乎锁定了所有到达服务器的请求,直到无限循环被“页面刷新”停止为止,一旦我刷新页面,其他请求就会立即处理
为什么服务器发送事件会导致这样的问题?
可以在这个问题中找到有关不同类型轮询的重要资源
一切看起来都很稳健,所以我猜测您受到了会话锁定的影响。PHP会话锁定会话文件,这样一次只有一个PHP脚本可以使用该会话;仔细想想,这是个好主意!
会话和 SSE 的问题在于 SSE PHP 进程永远运行,因此它永远锁定会话。如果任何其他 PHP 脚本尝试在同一会话中运行,它将被阻止(session_start()
我相信在调用时)。
这看起来是一篇关于这个主题的好文章;建议session_write_close()
您在知道不再需要该课程后立即致电。例如,如果您只需要使用会话来检查它们之前是否已对自己进行授权,那么您可以直接调用session_write_close()
,其他进程将不会被阻止。
归档时间: |
|
查看次数: |
1629 次 |
最近记录: |