一、遇到的问题:
在使用workerman中的http组件React\HttpClient\Client时出现分段响应的问题。
举个例子:正常返回的json字符串是“{'code':0,'mes':'success','data':'123456789'}”,异常返回“{'code':0,'mes':'success','data':'123”和“456789'}”两个json字符串。
二、原因分析(有大神做更正吗):
由于服务器生成HTTP回应是无法确定信息大小的,这时用Content-Length就无法事先写入长度,而需要实时生成消息长度,这时服务器一般采用Chunked编码(响应头里Transfer-Encoding:chunk)。
造成一次请求两个响应,上述返回的josn字符串被分割为两段。
三、解决方案:
<?php
$loop = React\EventLoop\Factory::create();
$client = new React\HttpClient\Client($loop);
$file = new \React\Stream\WritableResourceStream(fopen('sample.mp4', 'w'), $loop);
$request = $client->request('GET', 'http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4');
$request->on('response', function (\React\HttpClient\Response $response) use ($file) {
$size = $response->getHeaders()['Content-Length'];
$currentSize = 0;
$progress = new \React\Stream\ThroughStream();
$progress->on('data', function($data) use ($size, &$currentSize){
$currentSize += strlen($data);
echo "Downloading: ", number_format($currentSize / $size * 100), "%\n";
});
$response->pipe($progress)->pipe($file);
});
$request->end();
$loop->run();