事件源 - >服务器批量返回事件流,而不是以块的形式返回

I have a php script that import large data from csv files with validations.
For that I need to show progress to the user. I have used Event Streaming for that.
When I echo something, I want it to be transferred to client one by one instead of server sent whole output in bulk.
I had already played around with ob_start(), ob_implicit_flush() & ob_flush(), but they didn't work.
My script is working perfect on another server. Below server configurations are given:

Server configuration on which the code is not responding as desired, i.e.

OS: Linux
PHP Version 5.4.36-0+deb7u3
Server API: CGI/FastCGI 
Memory_limit: 128M
output_buffering: no value

As I have said, the code is working properly on another server which has the almost same configuration, i.e.

OS: Linux
PHP Version 5.4.37
Server API: CGI/FastCGI 
Memory_limit: 256MB
output_buffering: no value

Below is my sample code for sending event:

<?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) . "
"; // 2 kB padding for IE
echo "retry: 2000
";

// event-stream
$i = $lastEventId;

while ($i <= 100) {
    if($i==100){
        echo "data: stop
";
        ob_flush();
        flush();
        break;
    } else {
        echo "id: " . $i . "
";
        echo "data: " . $i . ";

";
        ob_flush();
        flush();
        sleep(1);
    }
    $i++;
}
?>

Below is my client page on which I need response:

<!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>
duanhuang1699
duanhuang1699 是的,它正在另一台服务器上运行......但不是新服务器
5 年多之前 回复
dongyongyin5339
dongyongyin5339 你的意思是你的实时httpstrimming正在其他服务器上工作????
5 年多之前 回复

3个回答



将chucked数据返回浏览器的最佳方法是使用Web Sockets让客户端打开文件阅读器的套接字然后你 可以将数据块化到浏览器而不会出现问题。</ p>

然后一旦完成,就可以关闭套接字。</ p>

一个很好的教程 用于网络套接字
http://www.phpbuilder.com/articles/application-architecture/optimization/creating-real-time-applications-with-php-and-websockets.html </ S> </ p>

使用这种方法,如果你想要实现验证,那么服务器不仅仅是发送块,而是通过javascript请求发送块</ p>

所以你的客户可以说 我需要块5,你的服务器实现类似</ p>

  $ requestedChunk = 5;  //这将由发送请求的javascript设置
$ chunkSize = 256; //这将是你的块大小;

$ readPossition = $ requestedChunk * $ chunkSize;
</ code> </ pre>

Link不再有效所以这里是一个建立在Ratchet上的 : https:// blog。 samuelattard.com/the-tutorial-for-php-websockets-that-i-wish-had-existed/ </ p>
</ div>

展开原文

原文

Your best method to return chucked data to the browser is to use Web Sockets get the client to open a socket to your file reader then you can chunk the data to the browser without a problem.

Then once it has finished you can close the socket.

a good tutorial for web sockets http://www.phpbuilder.com/articles/application-architecture/optimization/creating-real-time-applications-with-php-and-websockets.html

with this method you can then if you wanted implement verification so the server is not just sending chunks it's sends the chunks on request by javascript

So your Client could say i need chunk 5 and your server implement something like

$requestedChunk = 5; // this would be set by the javascript sending the request
$chunkSize = 256; // this would be your chunk size;

$readPossition = $requestedChunk * $chunkSize;

Link no longer works so here is one built on Ratchet: https://blog.samuelattard.com/the-tutorial-for-php-websockets-that-i-wish-had-existed/

douhe4608
douhe4608 它实际上是一个403只是显示404看你指向的地址,但使用谷歌“PHP WebSocket服务器示例”,你会发现很多
大约 2 年之前 回复
douxuanwei1980
douxuanwei1980 链接页面是404。
大约 2 年之前 回复



我遇到了类似的问题。 事件流在使用Apache 2.0处理程序的服务器上按预期工作(返回块),但不在使用FastCGI的服务器上(返回批量处理)。 我认为FastCGI中的某些东西是罪魁祸首,因此试图通过切换到CGI来解决问题。 现在事件流按预期工作。</ p>

无论是使用CGI还是FastCGI,Server API都显示为CGI / FastCGI,因此我假设它为您运行的服务器正在运行CGI和服务器 它不能用于运行FastCGI。 尝试将非工作服务器更改为CGI。</ p>

至于为什么它在FastCGI中不起作用我不完全确定,但除非它是必要的要求且CGI不可能然后 上述解决方案应该有效。 </ p>
</ div>

展开原文

原文

I had a similar problem. Event streams were working as expected (returning chunks) on a server using the Apache 2.0 Handler but not on a server using FastCGI (returning it in bulk). I assumed that something in FastCGI is the culprit and so tried to resolve the problem by switching to CGI. Now the event stream works as expected.

Whether using CGI or FastCGI the Server API shows up as CGI/FastCGI so I assume that the server it works on for you is running CGI and the server it doesn't work on for you is running FastCGI. Try changing the non-working server to CGI.

As for why it doesn't work in FastCGI I'm not entirely sure but unless it's a necessary requirement and CGI isn't possible then the above solution should work.

douwen5690
douwen5690 它不只是FastCGI /甚至mod_php都有这个问题
接近 5 年之前 回复



许多事情可以防止分块响应,例如但不限于; </ p>


  • Web服务器上的代理或任何其他缓冲机制</ li>
  • 当php.ini中的“输出缓冲”为“打开”时(您应该明确地将其设置为关闭)</ li>
  • 在Web服务器上启用gzip时</ li>
    </ ul>

    您应该首先检查这些。</ p>
    </ div>

展开原文

原文

Many things can prevent chunked response such as but not limited to;

  • Proxy or any other buffering mechanism on web server
  • When "Output buffering" is "on" in php.ini (you should explictly set it to off)
  • When gzip is enabled on web server

You should check these at first.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问