swooletw / laravel-swoole

High performance HTTP server based on Swoole. Speed up your Laravel or Lumen applications.
MIT License
4.03k stars 388 forks source link

调用chatgpt的流式响应输出有问题 #547

Closed laraveladmin-cn closed 8 months ago

laraveladmin-cn commented 10 months ago
Route::get('/streamswoole', function () {
    $class = '\\Symfony\\Component\\HttpFoundation\\StreamedResponse';
    $response = new $class(function (){
        $open_ai_key = 'sk-5OL';
        $open_ai = new OpenAi($open_ai_key);
        $txt = "";
        $opts = [
            'model' => 'gpt-3.5-turbo',
            'messages' => json_decode('[{
    "role": "system",
    "content": "You are a helpful assistant."
}, {
    "role": "user",
    "content": "今天星期几?"
}]',true),
            'temperature' => 1.0,
            'max_tokens' => 100,
            'frequency_penalty' => 0,
            'presence_penalty' => 0,
            'stream' => true
        ];
        $complete = $open_ai->chat($opts, function ($curl_info, $data) use (&$txt) {
            if ($obj = json_decode($data) and $obj->error->message != "") {
                error_log(json_encode($obj->error->message));
            } else {
                echo $data;
                $clean = str_replace("data: ", "", $data);
                $arr = json_decode($clean, true);
                if ($data != "data: [DONE]\n\n" and isset($arr["choices"][0]["delta"]["content"])) {
                    $txt .= $arr["choices"][0]["delta"]["content"];
                }
            }

            echo PHP_EOL;
            @ob_flush();
            @flush();
            return strlen($data);
        });
    },200,[
        'Access-Control-Allow-Origin'=>'*',
        'X-Accel-Buffering'=>'no',
        'Content-type'=>'text/event-stream',
        'Cache-Control'=>'no-cache'
    ]);
    return $response->send();
});
 sendMessage(){
            const eventSource = new EventSource('/streamswoole');
            const div = this.$refs['message'];

            eventSource.onmessage =  function (e){
                dd(e,1);
                if (e.data == "[DONE]") {
                    eventSource.close();
                } else {
                    let txt = JSON.parse(e.data).choices[0].delta.content
                    if (txt !== undefined) {
                        div.innerHTML += txt.replace(/(?:\r\n|\r|\n)/g, '<br>');
                    }
                }
            };
            eventSource.onerror =  function(e) {
                dd(e,2);
                eventSource.close();
            };
            dd(eventSource,3);
        }

php artisan swoole:http start 命令行控制台输出: 1694019591688 浏览器显示错误结果: 1694019688169 1694019744958

laravel不使用swoole的情况是对的:

image
Arkanius commented 8 months ago

Please, reopen in english