【发布时间】:2015-04-10 23:24:01
【问题描述】:
我有一个客户端发送一个需要很长处理时间的请求,客户端用 ajax 发送请求。一旦请求在服务器上被接受,客户端就会重定向到另一个页面,这是由 fastcgi_finish_request 完成的(我正在运行 php-fpm)
LongWork.php:
<?php
fastcgi_finish_request();
sleep(1000); //Simulate long computation time
?>
client.js:
$.ajax({
url: "...",
data: {},
success: function() {
top.location.href="next_page.php"
}
});
ajax 被发送并且成功回调导致重定向到 next_page.php 如预期的那样。
然后页面停止,直到睡眠结束我才得到任何服务。看起来我的连接正在等待 same php-fpm 进程完成
我正在使用 php-fpm 运行 nginx,知道为什么会发生这种情况吗?
编辑:
经过更多调查,我发现这种行为的原因是我有一个活动会话(来自 facebook SDK),当我在 LongWork.php 上销毁会话时:
<?php
session_destroy(); // Session was halting the client from accessing another page
fastcgi_finish_request();
sleep(1000); //Simulate long computation time
?>
您能否考虑一下这个解决方案?
我应该做一些不同于session_destroy()的事情
编辑:
根据 Lachlan Pease 的评论,我已将 session_destroy 切换为 session_write_close
【问题讨论】:
-
客户端是否使用 Internet Explorer? - 我相信除非您发送至少 255 个字符,否则它不会终止连接 - 尽管这可能只是旧版本。不知道,没用过。
-
@Leigh 问题是服务器上的会话,这在每个客户端都会重现,请参阅有问题的编辑
-
@ekeren,您应该能够使用 session_write_close() 而不是 session_destroy() 来解决这个问题 - 也就是说,我仍然会向 PHP 提交一个关于此的错误,这不是完全预期的行为编辑:实际上,考虑一下,这是预期的行为 - 默认情况下,如果用户的会话已经打开,PHP 将阻止。相反,您可以尝试仅在需要时在后续页面上打开会话;立即运行 session_start() 已成为习惯,但使用输出缓冲可以按需启动它而不会产生不良影响。
-
@LachlanPease 谢谢,它也有效。 session_destory 和 session_write_close 有什么区别?
-
@ekeren 不同的是 session_destroy 会删除服务器上的会话数据(即删除实际存储会话数据的文件),这样当你进入下一页时,用户会有一个空白会话。相比之下, session_write_close(或 session_commit,它的其他名称)只会将会话数据写入磁盘并释放 PHP 持有的锁。之后,对 $_SESSION 的任何新更改都不会更改,但在下一次请求时将可以使用其中的任何内容。
标签: ajax nginx session-state php