多AJAX请求延缓对方
我有我的网页长轮询请求。在服务器端脚本被设定20秒后超时。
I have a long polling request on my page. The script on the server side is set to timeout after 20 seconds.
所以,当长轮询是空转,并且用户presses另一个按钮,那新的请求发送被延迟,直到previous脚本超时。
So, when the long polling is "idling", and the user presses another button, the sending of that new request is delayed until the previous script times out.
我看不出什么毛病jQuery的侧面code。为什么的onclick事件延迟?
I can't see anything wrong with the code on jQuery side. Why is the onclick-event delayed?
function poll()
{
$.ajax({
url: "/xhr/poll/1",
data: {
user_id: app.user.id
},
type: "POST",
dataType: "JSON",
success: pollComplete,
error: function(response) {
console.log(response);
}
});
}
function pollComplete()
{
poll();
}
function joinRoom(user_id)
{
$.ajax({
url: "/xhr/room/join",
dataType: "JSON",
type: "POST",
data: {
user_id: app.user.id,
room_id: room.id
}
});
}
<button id="join" onclick="javascript:joinRoom(2);">Join</button>
############ PHP Controller on /xhr/poll
$time = time();
while ((time() - $time) < 20)
{
$updates = $db->getNewStuff();
foreach ($updates->getResult() as $update)
$response[] = $update->getResponse();
if (!empty($response))
return $response;
else
usleep(1 * 1000000);
return 'no-updates';
}
请问usleep是什么问题?
Could the "usleep" be the problem?
如果您在AJAX处理函数使用会话,你会到磁盘会话数据由第一个请求锁定的问题运行,所以每个后续请求最终等待它的收益会议收到的数据是可用的。实际上,这使得异步调用阻止另一个,你最终得到的线性响应时间顺序的要求 - 同步。 (这里的参考文章)
If you use sessions in the AJAX handling functions, you will run in to an issue where the disk session data is locked by the first request, so each subsequent request ends up waiting for the session data to be available before it proceeds. In effect, this makes asynchronous calls block one another, you end up with linear responses to the requests in chronological order - synchronous. (here's a reference article)
一个解决方案是使用 session_write_close
(文档)来关闭会话只要你不需要它了。这使得其他后续的请求继续,因为会话数据将被锁定。
A solution is to use session_write_close
(docs) to close out the session as soon as you don't need it any more. This allows other subsequent requests to proceed because the session data will be "unlocked".
不过,这可能会比较混乱,以及。如果你调用 session_write_close
返回响应权利之前,那么你不会自己做,因为会议将被尽快响应发送解锁任何好处。因此,它需要被尽早调用。如果您使用的是回后的建筑风格为AJAX请求,这并没有那么糟糕,但如果你有一个更大的框架,你的请求处理程序只是它的一部分,你必须探索更顶级的解决方案以非阻塞会话使用,以便您的子组件不关闭会话,该框架预计仍然是开放的。
This, however, can get confusing as well. If you call session_write_close
right before you return a response, then you aren't going to do yourself any favors because the session would have been unlocked as soon as the response was sent. Thus, it needs to be called as early as possible. If you are using post-back style architecture for AJAX request, this isn't so bad, but if you have a larger framework and your request handler is only a part of it, you'll have to explore a more top-level solution to non-blocking session usage so your subcomponents are not closing a session that the framework expects is still open.
一个途径是去与数据库会话。有优点和缺点,这个解决方案会超出这个答案的范围 - 检查谷歌进行详尽的讨论。另一条路线是使用打开会话,增加了一个变量的函数,然后将其关闭。你的风险的比赛条件下使用这一解决方案,但这里有一个大致的轮廓:
One route is to go with database session. There are pros and cons to this solution which are beyond the scope of this answer - check Google for exhaustive discussion. Another route is to use a function that opens a session, adds a variable, then closes it. You risk race conditions with this solution, but here's a rough outline:
function get_session_var($key, $default=null) {
if (strlen($key) < 1)
return null;
if (!isset($_SESSION) || !is_array($_SESSION)) {
session_start();
session_write_close();
}
if (array_key_exists($key, $_SESSION))
return $_SESSION[$key];
return $default;
}
function set_session_var($key, $value=null) {
if (strlen($key) < 1)
return false;
if ($value === null && array_key_exists($key, $_SESSION)) {
session_start();
unset($_SESSION[$key]);
} elseif ($value != null) {
session_start();
$_SESSION[$key] = $value;
} else {
return false;
}
session_write_close();
return true;
}