gpt4 book ai didi

javascript - 长轮询挂起所有其他服务器请求

转载 作者:行者123 更新时间:2023-11-30 19:36:07 29 4
gpt4 key购买 nike

我在我的网站上有一个简单的长轮询请求,以检查是否有任何新通知可供用户使用。就请求而言,一切似乎都完美无缺;只有在更新数据库(并为该特定用户创建了通知)后才会满足请求,并且之后会立即发送新请求。

问题


我注意到,当请求正在等待数据库的响应时(长轮询应该如此),对服务器的所有其他请求 会挂起 - 无论是媒体文件,< strong>AJAX 请求甚至新页面加载。这意味着对服务器的 所有请求都将挂起,直到我关闭浏览器并重新打开它。

更奇怪的是,如果我访问另一个我的 localhost网站(我的长投票是在 MAMP 虚拟主机网站上,www.example.com),它们没问题,我仍然可以像什么都没发生一样使用它们 - 尽管事实上它们技术上在同一个服务器。

我的代码


这是我在客户端 ( longpoll.js ):

window._Notification = {
listen: function(){
/* this is not jQuery's Ajax, if you're going to comment any suggestions,
* please ensure you comment based on regular XMLHttpRequest's and avoid
* using any suggestions that use jQuery */
xhr({
url: "check_notifs.php",
dataType: "json",
success: function(res){
/* this will log the correct response as soon as the server is
* updated */
console.log(res);
_Notification.listen();
}
});
}, init: function(){
this.listen();
}
}

/* after page load */
_Notification.init();

这就是我在服务器端的内容 ( check_notifs.php ):

header("Content-type: application/json;charset=utf-8", false);

if(/* user is logged in */){
$_CHECKED = $user->get("last_checked");

/* update the last time they checked their notifications */
$_TIMESTAMP = time();
$user->update("last_checked", $_TIMESTAMP);

/* give the server a temporary break */
sleep(1);

/* here I am endlessly looping until the conditions are met, sleeping every
* iteration to reduce server stress */
$_PDO = new PDO('...', '...', '...');
while(true){
$query = $_PDO->prepare("SELECT COUNT(*) as total FROM table WHERE timestamp > :unix");
if($query->execute([":unix" => $_CHECKED])){
if($query->rowCount()){
/* check if the database has updated and if it has, break out of
* the while loop */
$total = $query->fetchAll(PDO::FETCH_OBJ)[0]->total;
if($total > 0){
echo json_encode(["total" => $total]);
break;
}
/* if the database hasn't updated, sleep the script for one second,
* then check if it has updated again */
sleep(1);
continue;
}
}
}
}

/* for good measure */
exit;

我已经阅读了有关 NodeJS 和建议用于长轮询的各种其他框架,但不幸的是,它们目前对我来说遥不可及,我不得不使用 PHP 。我也环顾四周,看看 Apache 配置中是否有任何东西可以解决我的问题,但我只遇到了 How do you increase the max number of concurrent connections in Apache? ,考虑到我仍然可以使用我的其他 localhost,所提到的似乎不是问题。 同一服务器上的网站。

我真的很困惑如何解决这个问题,所以感谢所有帮助,
干杯。

最佳答案

实际发生的是 php 正在等待此脚本结束(锁定)以服务对同一文件的下一个请求。

As you can read here :

  • there is some lock somewhere -- which can happen, for instance, if the two requests come from the same client, and you are using file-based sessions in PHP : while a script is being executed, the session is "locked", which means the server/client will have to wait until the first request is finished (and the file unlocked) to be able to use the file to open the session for the second user.
  • the requests come from the same client AND the same browser; most browsers will queue the requests in this case, even when there is nothing server-side producing this behaviour.
  • there are more than MaxClients currently active processes -- see the quote from Apache's manual just before.

实际上某处有某种锁。您需要检查发生了什么锁。也许 $_PDO 有锁,您必须在 sleep(1) 之前将其关闭以保持解锁状态,直到您发出下一个请求。

您可以尝试提高您的 MaxClients 和/或申请 this answer

Perform session_write_close() (or corresponding function in cakephp) to close the session in the begin of the ajax endpoint.

关于javascript - 长轮询挂起所有其他服务器请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55938641/

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