我有一个长轮询脚本,用于查找数据库中的更改。如果数据发生变化,则退出while循环并将数据写入用户。长期民意调查"推动"与用户的航班连接。然后,用户可以单击连接并再次查看从MYSQL数据库中出来的旅行社的价格。
当长轮询空闲等待数据库更改时,此时用户触发第二个请求获取价格,然后第二个AJAX请求在第一个AJAX请求完成之前不响应。
我最初认为Sessions是问题因此我插入了session_write_close();对于漫长的民意调查脚本,但没有解决问题!社区可以帮助我解决这个问题吗?我不希望用户继续等待,直到长轮询结束!!!
服务器端长轮询:


require( 'wp-load.php' );
$unique_id = isset($_GET['unique_id']) ? $_GET['unique_id'] : null;
$last_ajax_call = isset($_GET['timestamp']) ? (float)$_GET['timestamp'] : 0;
$last_price_update = isset($_GET['timestamp_price']) ? (float)$_GET['timestamp_price'] : 0;
global $sortType;
$sortType = isset($_GET['sortType']) ? $_GET['sortType'] : null;
global $wpdb;
function getData($unique_id, $last_ajax_call) {
global $wpdb;
global $sortType;
if ($sortType == 'duration') {
$sortString = "order by duration asc, cheapest_price asc";
} else if ($sortType == 'price') {
$sortString = "order by cheapest_price asc, duration asc;";
} else {
$sortString = "order by total_rating asc, cheapest_price asc;";
}
$data = Array();
if ($wpdb->get_var("SHOW TABLES LIKE 'tl_connections_" . $unique_id . "'") == "tl_connections_" . $unique_id) {
$query = "SELECT timestamp FROM tl_connections_" . $unique_id . " WHERE timestamp > " . $last_ajax_call . " order by timestamp desc limit 1;";
$result = $wpdb->get_row($query, ARRAY_A);
$data[1] = $result['timestamp'];
$len = count($result);
if ($len == 1) {
$query = "SELECT content, timestamp FROM tl_connections_" . $unique_id . " WHERE timestamp > 1 " . $sortString;
$result = $wpdb->get_results($query, ARRAY_A);
$i = 0;
foreach ($result as $row) {
$data[0] = $data[0] . $row['content'];
//$wpdb->query("UPDATE tl_connections_" . $unique_id . " SET timestamp = 1000000000 where id = " . $row['id'] . ";");
}
}
}
//$wpdb->close();
return $data;
}
function getStatus($unique_id){
global $wpdb;
if($wpdb->get_var("SHOW TABLES LIKE 'tl_status_".$unique_id."'") == "tl_status_".$unique_id) {
$sql_status = "SELECT content FROM tl_status_".$unique_id." ORDER BY timestamp DESC LIMIT 1";
//echo $sql;
$last_row_status = $wpdb->get_row($sql_status);
$status = $last_row_status->content;
//echo "Last changed: ".$last_change_in_data_file;
}
return $status;
}
define('MESSAGE_POLL_MICROSECONDS', 500000);
// How long to keep the Long Poll open, in seconds
define('MESSAGE_TIMEOUT_SECONDS', 60);
// Timeout padding in seconds, to avoid a premature timeout in case the last call in the loop is taking a while
define('MESSAGE_TIMEOUT_SECONDS_BUFFER', 5);
session_write_close();
// Automatically die after timeout (plus buffer)
set_time_limit(MESSAGE_TIMEOUT_SECONDS+MESSAGE_TIMEOUT_SECONDS_BUFFER);
// Counter to manually keep track of time elapsed (PHP's set_time_limit() is unrealiable while sleeping)
$counter = MESSAGE_TIMEOUT_SECONDS;
// Poll for messages and hang if nothing is found, until the timeout is exhausted
while($counter > 0)
{
// Check for new data
$data = getData($unique_id, $last_ajax_call);
if($data[0])
{
// Break out of while loop if new data is populated
break;
}
else
{
// Otherwise, sleep for the specified time, after which the loop runs again
if (getStatus($unique_id)=="UpdatesComplete"){
break;
}
$wpdb->close();
usleep(MESSAGE_POLL_MICROSECONDS);
$wpdb->check_connection();
// Decrement seconds from counter (the interval was set in μs, see above)
$counter -= MESSAGE_POLL_MICROSECONDS / 1000000;
}
}
// If we've made it this far, we've either timed out or have some data to deliver to the client
if(isset($data[0]))
{
// Send data to client; you may want to precede it by a mime type definition header, eg. in the case of JSON or XML
$result = array(
'data' => $data[0],
'timestamp' => $data[1]);
$json = json_encode($result);
echo $json;
}
else {
$result = array(
'data' => "End",
'timestamp' => $data[1]);
$json = json_encode($result);
echo $json;
}


客户端长轮询


function getContent(timestamp, unique_id, direct_flight) {
console.log('Start Long Polling');
if (!jQuery('.offers_summary_detail_active').attr('data-type') === true) {
var sortType = "best";
} else {
var sortType = jQuery('.offers_summary_detail_active').attr('data-type');
}
jQuery('#content_unique_id').prop('value', unique_id);
jQuery('#content_direct_flight').prop('value', direct_flight);
ContentRequest = jQuery.ajax(
{
type: 'GET',
url: 'https://www.direktflug.de/tl_longpoll.php',
data: {timestamp: timestamp, unique_id: unique_id, sortType: sortType},
success: function (data) {
var obj = jQuery.parseJSON(data);
//console.log(obj.data);
div_inner.innerHTML = obj.data;
getContent(obj.timestamp, unique_id, direct_flight);
}
});
}


第二个AJAX请求的服务器端获取价格


require( 'wp-load.php' );
global $wpdb;
$unique_id = $_POST["unique_id"];
$outbound_id = $_POST["outbound_id"];
$inbound_id = $_POST["inbound_id"];
$query = "SELECT content FROM tl_prices_".$unique_id." WHERE outbound_id='".$outbound_id."' AND inbound_id='".$inbound_id."' ORDER BY price ASC, binary(agent_name) desc";
//echo $query;
//exit;
$prices = $wpdb->get_results($query);
foreach ( $prices as $price )
{
echo $price->content;
}