workerman/http-client 如何正确请求返回流式响应

wo3948

问题描述

最近在做一个ai 生成文字的项目,
使用 workerman/http-client 协程的写法,请求服务接口。(接口与 openai 的响应一致,是正常的),想实现边请求,边响应,读取内容的代码如下
`

public function getIterator(): Generator
{  
    while (!$this->response->getBody()->eof()) {

        $line = $this->readLine($this->response->getBody());

        dump($line);

        yield $response;
        // yield $this->responseClass::from($response);
    }
}

private function readLine(StreamInterface $stream): string
{
    $buffer = '';

    while (!$stream->eof()) {
        if ('' === ($byte = $stream->read(1))) {
            return $buffer;
        }
        $buffer .= $byte;
        if ($byte === "\n") {
            break;
        }
    }

    return $buffer;
}

`
但是现在发现 workerman/http-clien客户端好像只有完全读取响应以后才会输出。
更换了 guzzle\client 客户端,设置 stream =true 可以实现想要的效果,但是 guzzle 请求好像是阻塞的,无法同时响应多个,
所以想请问大佬有没有什么比价好的解决方案

502 1 3
1个回答

walkor

用2.1.0或则后续更高版本

composer require workerman/http-client ^2.1.0

用法类似

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Connection\TcpConnection;
use Workerman\Http\Client;
use Workerman\Protocols\Http\Chunk;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
use Workerman\Worker;

$worker = new Worker('http://0.0.0.0:1234');
$worker->onMessage = function (TcpConnection $connection, Request $request) {
    $http = new Client();
    $http->request('https://api.openai.com/v1/chat/completions', [
        'method' => 'POST',
        'data' => json_encode([
            'model' => 'gpt-3.5-turbo',
            'temperature' => 1,
            'stream' => true,
            'messages' => [['role' => 'user', 'content' => 'hello']],
        ]),
        'headers' => [
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer sk-xx',
        ],
        'progress' => function($buffer) use ($connection) {
            $connection->send(new Chunk($buffer));
        },
        'success' => function($response) use ($connection) {
            $connection->send(new Chunk(''));
        },
    ]);
    $connection->send(new Response(200, [
        //"Content-Type" => "application/octet-stream",
        "Transfer-Encoding" => "chunked",
    ], ' '));
};
Worker::runAll();
  • 10bang 2024-01-03

    直接市场购买官方的ai就知道怎样写了😎

  • wo3948 2024-01-03

    还是老大 威武,早知道就购买源码看一下了,卡了好几天了

  • tanhongbin 2024-01-03

    在webman中 能这么用嘛?

  • wo3948 2024-01-03

    好像不能直接用,需要自定义进程

  • tanhongbin 2024-01-03

    不能嘛?

🔝