当有另一个持久的PHP脚本运行时,没有php脚本可以在服务器上运行

时间:2015-12-02 08:45:13

标签: javascript php ajax apache http

我在服务器上运行了一个持久的PHP脚本。它将视频流式传输到服务器的video标签(不要问我为什么要这样做:-))。它可以运行几十分钟。

问题是,同时我想使用AJAX将请求发送到服务器,并且在长脚本停止之前不会发生。

我已经对这个问题进行了一些调查,我发现了一些奇怪的事情。

  • 虽然运行持久的PHP脚本,但我无法从同一浏览器调用任何PHP脚本(无论是否为AJAX)。
  • 同时从其他浏览器服务器访问没有问题。
  • 可以毫无问题地访问非php资产(图像,视频)。
  • 如果直接从.mp4文件播放视频,则问题不存在。可以在播放视频时处理对php的AJAX请求。

我很好奇可能导致这个问题的原因。从我看来,它可能是服务器和浏览器配置的组合。

我的问题是它为什么会发生,怎么解决?我希望能够在服务器上执行AJAX请求,而其他PHP脚本在同一浏览器中运行。

这是一个“卡住”的例子。要求。第一个请求是视频,第二个是我要发送的AJAX,它在第一个完成之前不会去任何地方。 enter image description here

第1次完成后,第2次立即完成。 enter image description here

Web服务器是Apache 2.它在IE和Chrome中被复制。

使用普通的jQuery&#39a $ .ajax()调用发送Ajax请求。

以下是阻止AJAX请求的视频请求的请求和响应信息。

Request GET /portal/portlet/index/id/671/call/proxyVideo?entityId=1 HTTP/1.1
Accept  */*
If-Unmodified-Since Fri, 24 Apr 2015 08:18:29 GMT
If-Match    "f91b54d-514740a87ff40"
Range   bytes=360448-261207372
User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Referer http://mm.mac/content
GetContentFeatures.DLNA.ORG 1
Pragma  getIfoFileURI.dlna.org
Accept-Language en-US
Accept-Encoding gzip, deflate
Host    mm.mac
Connection  Keep-Alive
Cache-Control   no-cache
Cookie  PHPSESSID=41821op72k2s24mfrsbn5gad64


Response    HTTP/1.1 206 Partial Content
Date    Tue, 01 Dec 2015 13:39:31 GMT
Server  Apache/2.4.16 (Unix) PHP/5.6.13
X-Powered-By    PHP/5.6.13
Expires Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control   no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma  no-cache
Last-Modified   Fri, 24 Apr 2015 08:18:29 GMT
ETag    "f91b54d-514740a87ff40"
Accept-Ranges   bytes
Content-Length  260846925
Access-Control-Allow-Methods    GET
Content-Range   bytes 360448-261207372/261207373
Keep-Alive  timeout=5, max=100
Connection  Keep-Alive
Content-Type    video/mp4

2 个答案:

答案 0 :(得分:4)

会话锁定

此问题可能是由会话锁定引起的。当持久的PHP脚本使用session_start()的会话时,该进程会锁定服务器上的会话文件,直到它完成。阻止尝试打开同一会话文件的所有其他PHP进程。

这就是为什么你在同一个浏览器中看到这种行为,而不是在另一台机器或不同的浏览器上(因为会话不同)。

您的问题的解决方案是使用

session_write_close();

每当您不需要写入会话时。您仍然可以在调用此函数时读取会话变量,但是对于另一个会话变量的写入,您需要使用session_start()再次打开会话。

你可以阅读很多这个问题here

一个例子:(来自链接页面)

// start the session
session_start();

// I can read/write to session
$_SESSION['latestRequestTime'] = time();

// close the session for writing
session_write_close();

// now do my long-running code.
// still able to read from session, but not write
$twitterId = $_SESSION['twitterId'];

//when you want to write again do session_start() before and close after.

答案 1 :(得分:0)

一次只有1个PHP脚本可以访问同一个用户会话 ,所有其他脚本将等到第一个脚本完成。

这是因为会话文件写锁定。

解决方案:

  1. 如果您不需要会话,请不要使用会话(在您的长脚本中) 或
  2. 尽快调用session_write_close()来解锁会话文件 http://php.net/manual/en/function.session-write-close.php