关于workerman/http-client的一个疑问

岛屿可以找到海

问题描述

$http->request($host.$url, [
            'method' => 'POST',
            'data' => json_encode($data),
            'headers' => $header,
            'progress' => function ($buffer) use ($userConnection, $http) {

                if ($http->incompleteData!=""){
                    $buffer=$http->incompleteData.$buffer;//将上次不完整数据和本次不完整数据拼接
                    $http->incompleteData='';//重置不完整数据
                }

                $result = $this->parsedData($buffer);

                $content=$result['content'];

                $incompleteData=$result['incompleteData'];//不完整数据
                if ($incompleteData!=""){
                    $http->incompleteData.=$incompleteData;//设置不完整数据
                }
                if ($content!="") {
                        $userConnection->send(new Chunk($content));
                        $http->buffer .= $content;
                        $http->incompleteData='';
                }

            },
            'success' => function ($response) use ($userConnection, $http,$model,$saveMessage_callback, $deduction_callback,$updateKey_callback) {
                $userConnection->send(new Chunk(''));
                call_user_func($saveMessage_callback, $http->buffer);
                $error=json_decode($http->buffer,true);

                // 扣费
                if ($response->getStatusCode() == 200&&!is_array($error)) {
                  //响应200且不能是json格式,因为有时候响应200但是时间是不是正常回复
                   call_user_func($deduction_callback);
                   Redis::incr($model);//记录相应模型使用次数
                 }
                //更新key的使用时间
                call_user_func($updateKey_callback);

            },'error' => function ($exception)use($userConnection,$updateKey_callback,$http,$saveMessage_callback) {
                $userConnection->send(new Chunk(''));
                call_user_func($updateKey_callback);
                //错误或者超时也保存聊天记录
                call_user_func($saveMessage_callback, $http->buffer);
        }
        ]);

上述代码无法正常发送chunk响应给客户端,但是如果加一个print打印,那么客户端就能收到响应

$http->request($host.$url, [
            'method' => 'POST',
            'data' => json_encode($data),
            'headers' => $header,
            'progress' => function ($buffer) use ($userConnection, $http) {

            print_r($buffer);//这里打印一下,前端就可以接受到chunk响应

                if ($http->incompleteData!=""){
                    $buffer=$http->incompleteData.$buffer;//将上次不完整数据和本次不完整数据拼接
                    $http->incompleteData='';//重置不完整数据
                }
                $result = $this->parsedData($buffer);
                $content=$result['content'];
                $incompleteData=$result['incompleteData'];//不完整数据
                if ($incompleteData!=""){
                    $http->incompleteData.=$incompleteData;//设置不完整数据
                }
                if ($content!="") {
                        $userConnection->send(new Chunk($content));
                        $http->buffer .= $content;
                        $http->incompleteData='';
                }
            },
            'success' => function ($response) use ($userConnection, $http,$model,$saveMessage_callback, $deduction_callback,$updateKey_callback) {
                $userConnection->send(new Chunk(''));
                call_user_func($saveMessage_callback, $http->buffer);
                $error=json_decode($http->buffer,true);
                // 扣费
                if ($response->getStatusCode() == 200&&!is_array($error)) {
                  //响应200且不能是json格式,因为有时候响应200但是时间是不是正常回复
                   call_user_func($deduction_callback);
                   Redis::incr($model);//记录相应模型使用次数
                 }
                //更新key的使用时间
                call_user_func($updateKey_callback);
            },'error' => function ($exception)use($userConnection,$updateKey_callback,$http,$saveMessage_callback) {
                $userConnection->send(new Chunk(''));
                call_user_func($updateKey_callback);
                //错误或者超时也保存聊天记录
                call_user_func($saveMessage_callback, $http->buffer);
        }
        ]);

这是什么原因呢?

破案了与程序无关,是第三方接口的问题...

473 1 0
1个回答

Gin

应该先返回个 chunk信息通知请求端 后续通过 progress返回
return response()->withHeaders([
"Content-Type" => "application/json",
"Transfer-Encoding" => "chunked",
]);
https://www.workerman.net/doc/workerman/components/workerman-http-client.html

  • 岛屿可以找到海 2024-06-25

    我代码没截完整,我写了这个响应了
    return response()->withHeaders([
    "Content-Type" => "application/json",
    "Transfer-Encoding" => "chunked",
    ]);
    ,如果没加这个响应头,那我就算写了print打印前端也无法接受到响应啊

  • 岛屿可以找到海 2024-06-25

    不能啊,亲测加一个print或者别的一个什么别的操作,前端就都能收到响应,我查了一下貌似和缓冲区有关系

  • Gin 2024-06-25

    走nginx代理没有 proxy_buffering off; 有没有

  • 岛屿可以找到海 2024-06-25

    proxy_buffering off设置了
    但是我目测和NGINX无关,我本地测试也会出现这个问题

  • 岛屿可以找到海 2024-06-25

    破案了,是第三方接口的问题,请求空回复的时候是第三方接口报500了......

×
🔝