请教如何在webman 控制器流式返回

wo3948

问题描述

购买了 AI 插件基础版本,想把流式输出移植到自己的程序里面,现在发现客户端请求程序以后在控制台能正常输出响应,但是客户端 连接报错,无法流式返回,想请问下问题可能出在哪里

   public function chat(Request $request)
    {
        $input = $request->all();
        if (empty($input['id'])) {
            $this->error('error id is empty');
        }

        $connection = $request->connection;

        $appInfo = ChatApp::find($input['id']);

        $token = $appInfo['token'];

        $varialbes = [];

        if (!empty($request->input('variable', ''))) {

            $varialbes = json_decode($request->input('variable', ''), 1);
        }

        $msg = $request->input('msg', '简短回答你是谁');

        $client = new AIArticleStream();
        $client->gpt_chat($msg, $token, $varialbes);
        $buffer = $client->build_tcp_data();

        [$schema, $address] = explode('://', $client->url, 2);
        $con = new AsyncTcpConnection("tcp://{$address}", ['ssl' => [
            'verify_peer' => false,
        ]]);
        $con->transport = 'ssl'; //in_array($schema, ['wss', 'https']) ? 'ssl' : 'tcp'; 
        $callback = ''; 

        $con->send($buffer);
        $con->buffer = '';

        // 失败时
        $con->onError = function ($con, $code, $msg) use ($connection) {
            echo $code, $msg;
            $con->buffer = $msg;
            if ($connection) {
                $connection->send(new Chunk(json_encode(['error' => ['message' => $msg]])));
                $connection->send(new Chunk(''));
            }
        };

        $con->onMessage = function ($con, $buffer) use ($connection) {
            static $headerCompleted = false, $header = '', $bodyLength = 0, $sentLength = false;
            if ( !$headerCompleted) {
                $header .= $buffer;
                if (!$position = strpos($header, "\r\n\r\n")) {
                    return;
                }
                if (preg_match("/Content-Length: (\d+)\r\n/i", $header, $match)) {
                    $bodyLength = $match[1];
                }
                if(!$buffer = substr($header, $position + 4)) {
                    return;
                }
                $headerCompleted = true;
                if ($bodyLength) {
                    $con->buffer .= $buffer;
                    if ($connection) {
                        $sentLength += strlen($buffer);
                        $connection->send(new Chunk($buffer));
                        if ($sentLength >= $bodyLength) {
                            $connection->send(new Chunk(''));
                        }
                    }
                    return;
                }
            }

            dump($buffer);
            $con->buffer .= $buffer;
            if ($connection) {

                if ($bodyLength) {

                    $sentLength += strlen($buffer);
                    $connection->send(new Chunk($buffer));
                    if ($sentLength >= $bodyLength) {
                        $connection->send(new Chunk(''));
                    }
                } else {

                    $connection->send($buffer, true);
                }
            }
        };

        // 关闭
        $con->onClose = function ($con) use ($connection) {
            dump('---conn close---');
            if ($con->buffer) {
                // call_user_func($callback, $handler->formatResponse($con->buffer));
            }
        };

        $con->connect();

        // 向浏览器发送头部响应
        return response("\n")->withHeaders([
            "Content-Type" => "application/octet-stream",
            "Transfer-Encoding" => "chunked",
        ]);

    }

截图

431 1 0
1个回答

wo3948

已解决。 没有仔细看文档,nginx 反向代理的 header 设置出问题了

  • Tinywan 2024-01-25

    nginx 反向代理的 header 哪里出问题了呢!麻烦贴一下哦

  • wo3948 2024-01-25

    我们这边用的是宝塔面板, 用面板里面反向代理功能添加了代理,后来排查配置文件,应该是缺少了这句 proxy_set_header Connection ""; 所以导致了header 有问题

  • Tinywan 2024-01-25

    好的

🔝