對(duì)接文心一言,前端是fetch請(qǐng)求,后端使用AsyncTcpConnection請(qǐng)求后流式返回?cái)?shù)據(jù),但是前端一直是請(qǐng)求尚未完成
/**
* 流式對(duì)話
*/
public function conversation()
{
//流式對(duì)話api
$conversationApi = "https://agentapi.baidu.com/assistant/conversation?appId={$this->client_id}&secretKey={$this->client_secret}";
$user_connection = request()->connection;
$post = request()->post();
$adminUser = request()->adminUser;
try {
$parse_url = parse_url($conversationApi);
$connection = new AsyncTcpConnection("tcp://{$parse_url['host']}", ['ssl' => [
'verify_peer' => false,
]]);
$connection->transport = in_array($parse_url['scheme'], ['wss', 'https']) ? 'ssl' : 'tcp';
//建立鏈接時(shí),發(fā)送請(qǐng)求數(shù)據(jù)
$connection->onConnect = function($connection) use($parse_url, $post, $adminUser) {
// 準(zhǔn)備POST數(shù)據(jù),包括appId
$postData = json_encode([
'message' => [
'content' => [
'type' => 'text',
'value' => [
'showText' => $post['content']
]
]
],
'source' => $this->client_id,
'from' => 'openapi',
'openId' => $adminUser['tel'] . '_' . $adminUser['id'],
]);
// 構(gòu)建HTTP POST請(qǐng)求
$httpRequest = "POST {$parse_url['path']}?{$parse_url['query']} HTTP/1.1\r\n" .
"Host: agentapi.baidu.com\r\n" .
"Content-Type: application/json\r\n" .
"Content-Length: " . strlen($postData) . "\r\n" .
"Connection: close\r\n\r\n" .
$postData;
// 發(fā)送HTTP POST請(qǐng)求
$connection->send($httpRequest);
};
//當(dāng)收到消息的時(shí)候
$connection->onMessage = function ($connection, $http_buffer) use($user_connection) {
//如果消息中包含event:message才是消息,
if (strpos($http_buffer, 'event:message') !== false) {
//分割成數(shù)組
$buffer = explode('event:message', $http_buffer);
//取最后一個(gè)
$buffer = end($buffer);
//去掉末尾的換行符
$buffer = rtrim($buffer);
$user_connection->send(new Chunk($buffer));
}
};
//關(guān)閉鏈接時(shí)
$connection->onClose = function($user_connection) {
$user_connection->send(new Chunk(''));
};
//鏈接錯(cuò)誤時(shí)
$connection->onError = function($connection, $code, $msg) use($user_connection) {
$user_connection->send(new Chunk(''));
};
//建立鏈接
$connection->connect();
} catch (\Exception $e) {
abort($e->getMessage());
}
return response()->withHeaders([
'Content-Type' => 'application/octet-stream',
"Transfer-Encoding" => "chunked",
]);
}