事件源->服务器以批量形式返回事件流,而不是以块形式返回
Event Source -> Server returns event stream in bulk rather then returning in chunk
我有一个php脚本,可以通过验证从csv文件导入大数据
为此,我需要向用户显示进度。我已经为此使用了事件流
当我回显某个东西时,我希望它一个接一个地传输到客户端,而不是服务器批量发送整个输出
我已经玩过ob_start()、ob_implicit_flush()&ob_flush(),但它们不起作用
我的脚本在另一台服务器上运行得很好。给出了以下服务器配置:
代码未按要求响应的服务器配置,即
OS:LinuxPHP版本5.4.36-0+deb7u3服务器API:CGI/FastCGI内存限制:128Moutputbuffering:无值
正如我所说,代码在另一台配置几乎相同的服务器上正常工作,即
OS:LinuxPHP版本5.4.37服务器API:CGI/FastCGI内存限制:256MBoutputbuffering:无值
下面是我发送事件的示例代码:
<?php
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Access-Control-Allow-Origin: *");
$lastEventId = floatval(isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? $_SERVER["HTTP_LAST_EVENT_ID"] : 0);
if ($lastEventId == 0) {
$lastEventId = floatval(isset($_GET["lastEventId"]) ? $_GET["lastEventId"] : 0);
}
echo ":" . str_repeat(" ", 2048) . "'n"; // 2 kB padding for IE
echo "retry: 2000'n";
// event-stream
$i = $lastEventId;
while ($i <= 100) {
if($i==100){
echo "data: stop'n";
ob_flush();
flush();
break;
} else {
echo "id: " . $i . "'n";
echo "data: " . $i . ";'n'n";
ob_flush();
flush();
sleep(1);
}
$i++;
}
?>
以下是我需要回复的客户页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>EventSource example</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script src="../jquery/eventsource.js"></script>
<script>
var es = new EventSource("events.php");
var listener = function(event) {
console.log(event.data);
var type = event.type;
if (event.data == 'stop') {
es.close();
} else {
var div = document.createElement("div");
div.appendChild(document.createTextNode(type + ": " + (type === "message" ? event.data : es.url)));
document.body.appendChild(div);
}
};
var errlistener = function(event) {
es.close();
}
es.addEventListener("open", listener);
es.addEventListener("message", listener);
es.addEventListener("error", errlistener);
</script>
</head>
<body>
</body>
</html>
将丢弃的数据返回到浏览器的最佳方法是使用Web套接字。让客户端打开一个指向文件读取器的套接字,然后就可以毫无问题地将数据块到浏览器。
然后,一旦它完成,你可以关闭插座。
一个很好的websocket教程http://www.phpbuilder.com/articles/application-architecture/optimization/creating-real-time-applications-with-php-and-websockets.html
使用这种方法,如果你想实现验证,那么服务器就可以不只是发送块,而是通过javascript 根据请求发送块
所以你的客户可以说我需要区块5,而你的服务器实现了类似的东西
$requestedChunk = 5; // this would be set by the javascript sending the request
$chunkSize = 256; // this would be your chunk size;
$readPossition = $requestedChunk * $chunkSize;
链接不再工作,因此这里是一个基于棘轮的链接:https://blog.samuelattard.com/the-tutorial-for-php-websockets-that-i-wish-had-existed/
我也遇到了类似的问题。事件流在使用Apache 2.0处理程序的服务器上按预期工作(返回块),但在使用FastCGI的服务器上不工作(批量返回)。我认为FastCGI中的某些东西是罪魁祸首,因此试图通过切换到CGI来解决问题。现在事件流按预期工作。
无论是使用CGI还是FastCGI,服务器API都显示为CGI/FastCGI,因此我假设它为您工作的服务器正在运行CGI,而它不为您运行的服务器则在运行FastCGI。尝试将不工作的服务器更改为CGI。
至于为什么它在FastCGI中不起作用,我不完全确定,但除非这是必要的要求,并且CGI不可能,否则上述解决方案应该起作用。
许多事情可以阻止分块响应,例如但不限于;
- web服务器上的代理或任何其他缓冲机制
- 当php.ini中的"输出缓冲"为"on"时(您应该明确地将其设置为off)
- 当在web服务器上启用gzip时
你应该先检查一下这些。
- 从控制器返回后Ajax启动事件激发
- 如何获取事件的返回值
- 为什么我的on change事件在ie9上返回空
- Jquery contextenu事件总是返回e.which作为0
- 当使用“”时,事件数据在jquery中返回空对象;on()”;
- 如何在提示下获取和使用从window.onbeforeunload事件的返回语句显示的值
- 访问新创建的Facebook事件返回false
- 为什么asp:LinkButton服务器端事件没有'当clientClick返回true时,t激发
- 为什么不是't单击事件中返回的数组的总和
- Google Map KML层占位符点击事件返回ZERO_RESULTS
- 事件源->服务器以批量形式返回事件流,而不是以块形式返回
- CoffeeScript - 这个奇怪的“返回”事件是什么意思
- 如何返回事件侦听器调用的函数的值
- 多个 document.createElement 在一个函数中返回事件侦听器
- 锤子.js 2.0 使用 jquery 插件时不返回事件选项
- 计算并返回事件处理函数的值
- 当allDay为真时,fullcalendar返回事件结束null
- 只有当模态可见时,才让ESC触发返回事件
- 为什么.next()返回事件's对象本身?
- 如何检测该函数是否仍在运行?或者我可以钩入返回事件