最近在研究openai的接口,它有一個(gè)steam功能,就是在curl時(shí)設(shè)置 CURLOPT_WRITEFUNCTION 屬性,可以不停的回調(diào)這個(gè)函數(shù)并輸出流到瀏覽器,官方示例差不多是這樣子:
$open_ai->completion($opts, function ($curl_info, $data) {
echo $data . "<br>"; //不停輸出數(shù)據(jù)
ob_flush();
flush();
return strlen($data);
});
用php原生,瀏覽器會(huì)不停的輸出數(shù)據(jù),但webman的echo是輸出到控制臺(tái)的,所以請(qǐng)問(wèn)如何在這個(gè)回調(diào)函數(shù)里向?yàn)g覽器實(shí)時(shí)發(fā)送數(shù)據(jù)流呢?
謝謝各路大神駐留幫助~
創(chuàng)建 process/HttpChunk.php
<?php
namespace process;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Chunk;
use Workerman\Protocols\Http\Response;
use Workerman\Timer;
class HttpChunk
{
public function onMessage(TcpConnection $connection, Request $request)
{
// 首先發(fā)送一個(gè)帶Transfer-Encoding: chunked頭的Response響應(yīng)
$total_count = 10;
$connection->send(new Response(200, array('Transfer-Encoding' => 'chunked'), "共{$total_count}段數(shù)據(jù)<br>"));
$timer_id = Timer::add(2, function () use ($connection, &$timer_id, $total_count){
static $count = 0;
// 連接關(guān)閉的時(shí)候要將定時(shí)器刪除,避免定時(shí)器不斷累積導(dǎo)致內(nèi)存泄漏
if ($connection->getStatus() !== TcpConnection::STATUS_ESTABLISHED) {
Timer::del($timer_id);
return;
}
if ($count++ >= $total_count) {
// 發(fā)送一個(gè)空的''代表結(jié)束響應(yīng)
$connection->send(new Chunk(''));
return;
}
// 發(fā)送chunk數(shù)據(jù)
$connection->send(new Chunk("第{$count}段數(shù)據(jù)<br>"));
});
}
}
config/process.php 怎加配置
<?php
return [
// ... 其它配置 ...
'http-chunk' => [
'listen' => 'http://0.0.0.0:8585',
'handler' => \process\HttpChunk::class,
]
];
瀏覽器訪問(wèn) http://127.0.0.1:8585
頁(yè)面會(huì)定時(shí)輸出數(shù)據(jù)
http://m.wtbis.cn/doc/workerman/http/response.html#%E5%8F%91%E9%80%81http%20chunk%E6%95%B0%E6%8D%AE
http://m.wtbis.cn/doc/workerman/http/SSE.html