gpt4 book ai didi

javascript - PHP Curl 超时导致 Javascript 客户端崩溃

转载 作者:搜寻专家 更新时间:2023-10-31 21:02:31 24 4
gpt4 key购买 nike

我有一个向设备发送 CURL 请求的自动同步,我对我拥有的每台设备(比如 60 台)都执行此请求。问题是:
- 如果通信成功,一切正常。
- 但如果通信失败,网页将等待直到超时消失。所以客户端崩溃了 3-4 分钟......我有重要的网格在 3-4 分钟内停止加载数据。

自动同步是 javascript 中的一个函数,它执行 AJAX 请求以调用下面的 php Controller 。我怎样才能防止这种情况发生?我不知道还能尝试什么...AJAX 是异步的,所以我不明白为什么网页会停止。

Controller :

$list = $panels_repository->getNetwork();

$thread = new PollingThread($list);
$thread->start();
$thread->join();

$result = $thread->result;
$resultLength = sizeof($result);

//...

主题:

class PollingThread extends Thread {
private $panels_list;
private $alarm_status;
public $result;

public function __construct($list) {
$this->panels_list = $list;
}

public function run() {
$panels_list = $this->panels_list;

$alarmsUpdated = array();
$panels = array();

foreach($panels_list as $panel) {
$alarms_list = $panel->getAlarmsList();

//Get updated alarms status
$panel->getDiagnosticStatus($alarms_list);

//Save the results
array_push($alarmsUpdated, $alarms_list);
}

$this->result = $alarmsUpdated;

}

获取诊断状态

$input = "<?xml version='1.0' encoding='ISO-8859-1'?>
<?getParameters message?>
<displayMLRequest xmlns='http://www.peek.se/DisplayML/' version='1.12'
dateTime='2008-01-10T15:09:51+02:00'>
<getParameters/>
</displayMLRequest>";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url); //Set IP to communicate

//Set POST XML Input
curl_setopt( $ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $input);

//Return response as string & TimeOuts
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);

//Execute
$output = curl_exec($ch);

$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

curl_close($ch);

Javascript:

    $('#stations_tree').on('changed.jstree', function (e, data) {
//....

var dataObject = {
type: "Selected",
childrenID: childrenID_array,
parentsID: parentsID_array
};

$.ajax({
type: "POST",
url: "controllers/PanelsController/",
data: dataObject,
cache: false,
success: function ()
{
$("#dg_selected_stops").jsGrid("loadData");
$("#dg_selected_pids").jsGrid("loadData");
}
});

}).jstree({
plugins: ["checkbox", "state", "types"],
"types": {
"default": {
"icon" : false
}
},
core: {
data: {
url: "json/stations.json",
dataType: "json",
success: function () {
//Save Panels Network as session variable
var dataObject = {
type: "Network"
};

$.ajax({
type: "POST",
url: "controllers/PanelsController/",
data: dataObject,
cache: false,
success: function() {
//Get EquipmentStatus for each panel
var dataType = {
type: "Save"
};

$.ajax({
type: "POST",
url: "controllers/EquipmentStatusController/",
data: dataType,
cache: false,
success: function () {
//Status Unknown
changeTreeIcons();
loadAlarmsData();

polling();
}
});
}
});
}
}
}
});

函数 polling() - JS 停止直到超时结束

function polling() {
var dataObject = {
type: "Polling",
};

$.ajax({
type: 'POST',
url: "controllers/DatabaseController/",
data: dataObject,
success: function(response) {
//loadAlarmsData();
//changeTreeIcons();
}
});

编辑: 我已经检查过,如果我在轮询开始后尝试执行 AJAX 请求,网页只会在 php 脚本完成后执行该请求。因此,阻塞的 JS 是使用 ajax 请求加载数据的表。我该如何解决这个问题?

最佳答案

它不是复制/粘贴的完整解决方案,但它可以让您了解如何解决您的问题。您可以尝试下一步(仅限 php-fpm)。

在前端使用 js 运行同步并调用你的 Controller ,在 Controller 的客户端为浏览器发送响应并调用 fastcgi_finish_request()在您的 CURL 操作开始之前。此函数将所有响应数据刷新到客户端并完成请求,但 PHP 脚本继续工作。

...

$list = $panels_repository->getNetwork();

$key = 'my_unique_operation_key'; // it key need you for get data on client side
$resp = [
'status'=>'start',
'operation_key' => $key
];
echo json_encode($resp);
fastcgi_finish_request(); // close connection and continue ...

$thread = new PollingThread($list, $key); // send $key also
...

在轮询线程中:

...
foreach($panels_list as $panel) {
$alarms_list = $panel->getAlarmsList();

//Get updated alarms status
$panel->getDiagnosticStatus($alarms_list);

//Save the results
array_push($alarmsUpdated, $alarms_list);

...
// save operation progress for example in memcache
$progressData = some data about progress and $alarmsUpdated, etc...
$memcache_obj->set('operation_'.$key, json_encode($progressData));
}

在 Controller 的某处添加返回数据部分的操作:

function getDataPartially_action(){
$key = $_GET['key']; // not forget validate
...
$jsonData = $memcache_obj->get('operation_'.$key); // get current state from memcache by key
echo $jsonData;
exit();
}

在前端:

// call controller and start operation
$.ajax({
url: '/controller/uri/here',
beforeSend: function() {
// here you can place spinner or progress bar ...
},
success: function(json) {
// in json you get progress key after fastcgi_finish_request()
// and run visual progress
getDataPartially(key);
}
});

// load data partially
function getDataPartially(key){
var timerId = setInterval(function() {
$.ajax({
url: '/controller/uri/here/getDataPartially_action?key=' + key,
success: function(json) {
// in json you have data for grids and progress info
// if json contains finish info stop progress
clearInterval(timerId);
// hide progress bar and etc ...
}
});}, 2000);
}

附注在 CURL 函数中,您可以使用 CURLOPT_PROGRESSFUNCTION并获取有关进度的更多信息:

$ch = curl_init();
curl_setopt ...
curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, 'curl_progress_callback');
...
// where curl_progress_callback is:

function curl_progress_callback($dltotal, $dlnow, $ultotal, $ulnow){
$curlInfo = curl_getinfo($ch); // a lot info about connection
echo $curlInfo['connect_time'];
echo $curlInfo['http_code'] ...
}

关于javascript - PHP Curl 超时导致 Javascript 客户端崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39230944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com