PHP后台脚本阻止整个浏览器的连接
我有以下问题:
通过 Ajax 调用 PHP 脚本。脚本本身使用以下几行关闭连接
ignore_user_abort(true);
header("Content-Length: 0");
header("Connection: close");
flush();
,然后开始使用 phpMailer 在后台发送一堆邮件(循环并在每封邮件后使用 sleep(1) - 将来我希望这是随机数量的发送 5 封邮件后的秒数)。使用FireBug,我可以看到与脚本的连接被直接终止。邮件也正在发送中。
但是,当脚本在后台运行时,我无法打开任何页面 - 它们会一直加载,直到后台脚本明显完成为止。奇怪的是:该脚本似乎并没有阻止整个服务器,因为连接限制仅适用于启动后台脚本的浏览器。因此,在我在 FireFox 中启动脚本后,我仍然可以在 Chrome 中访问服务器上的页面。
可能是什么原因?每个浏览器打开的 MYSQLi 连接数是否有限制(每个会话,即...) - 我找不到任何关于此的内容...或者浏览器(尽管 FireBug 说连接已终止)仍在等待脚本的响应?
我该如何解决这个问题? 预先感谢您的任何帮助。
I have the following problem:
A PHP Script is called via Ajax. The script itself closes the connection using the following lines
ignore_user_abort(true);
header("Content-Length: 0");
header("Connection: close");
flush();
and then starts sending out a bunch of mails in the background using phpMailer (in a loop and using sleep(1) after each mail - in the future I want this to be a random amount of seconds after 5 sent mails). Using FireBug, I can see that the connection to the script is directly terminated. The mails are being sent as well.
However, I cannot open any pages while the script is running in the background - they keep loading until the background script obviously has finished. The strange thing: The script doesn't seem to block the whole server, as the connection restriction only applies to the browser that initiated the background script. So after I start the script in - let's say - FireFox, I can still access the pages on the server in Chrome.
What could be the cause? Is there a limit of open MYSQLi-connections per browser (per session, that is...) - I couldn't find anything on this... Or is the browser (although FireBug says that the connection has been terminated) nevertheless waiting for a response of the script?
How could I solve this?
Thanks in advance for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
PHP 脚本无法关闭客户端->服务器连接,除非退出。执行
Connection: close
标头也不会执行任何操作,因为这是针对客户端->服务器请求的,并且无论如何都是默认操作,除非客户端专门请求Connection: keep-alive
。您看到的“在其他浏览器中有效”行为通常是由于 PHP 在请求处于活动状态时锁定会话文件造成的。不同的浏览器不会共享 cookie,因此每个浏览器都有自己单独的会话。因此,虽然 Firefox 与此后台请求相关,但 Chrome 正在使用的会话完全不受影响。
如果您希望在等待此邮件脚本处理时继续使用 FF,请在进入邮件程序循环之前发出
session_write_close()
。这将关闭并解锁会话文件,并让您继续在 FF 的另一个选项卡中使用该站点。如果您希望此脚本真正独立于浏览器,那么它必须 pcntl_fork 本身进入后台。这个分叉的子进程可以处理整个过程,完全不附加到浏览器,并且原始脚本可以退出,从而允许关闭连接。
A PHP script cannot close the client<->server connection except by exiting. doing a
Connection: close
header doesn't do anything either, as that's for client->server requests, and is the default action anyways, unless the client specifically requestsConnection: keep-alive
.The "works in other browsers" behavior you're seeing is generally due to PHP locking the session file while a request is active. The different browsers won't share cookies, so each browser has its OWN separate session. So while Firefox is tied up with this background request, the session that Chrome is using is completely unaffected.
If you want to continue being able to use FF while it's waiting for this mail script to process, then issue a
session_write_close()
before you enter the mailer loop. That will close and unlock the session file, and let you continue using the site in another tab of FF.If you want this script to be truly independent of the browser, then it'll have to pcntl_fork itself into the background. This forked child can handle the processing, completely unattached to a browser, and the original script can exit, allowing the connection to close.