用了wrench/wrench 组件 compose require wrench/wrench
<?php
namespace app\extend;
use think\facade\Env;
use think\facade\Log;
use Wrench\Client;
class Xfyun
{
private $host = "spark-api.xf-yun.com";
private $version = "/v1.1/chat";
private $header = [];
private $query = [];
function __construct(){
$this->host = Env::get("xfyun.HOST");
}
private function makeSign(){
$date = gmdate('D, d M Y H:i:s') . ' GMT';
// $date ="Fri, 05 May 2023 10:43:39 GMT";
$tmp = "host: " .$this->host. "\n";
$tmp .= "date: " .$date. "\n";
$tmp .= "GET " .$this->version. " HTTP/1.1";
//var_dump( $tmp);
$this->header = explode("\n", $tmp);
$signature = hash_hmac('sha256', $tmp, Env::get("xfyun.APISECRET"), true);
$tmpSha = base64_encode($signature);
return [$date , $tmpSha];
}
function makeUrl(){
list($date, $sign) = $this->makeSign();
$authorization = "api_key=\"".Env::get("xfyun.apikey")."\", algorithm=\"hmac-sha256\", headers=\"host date request-line\", signature=\"".$sign."\"";
$authorization = base64_encode($authorization);
$query = [
"authorization" => $authorization,
"date"=>$date,
"host" => $this->host,
];
$this->query = $query;
return sprintf("ws://%s%s?%s", $this->host, $this->version, http_build_query($query));
}
function send($question , $deviceId){
$data = array(
"header" => array(
"app_id" => Env::get("xfyun.APPID"),
"uid" => $deviceId
),
"parameter" => array(
"chat" => array(
"domain" => "general",
"random_threshold" => 0.5,
"max_tokens" => 2048,
"auditing" => "default"
)
),
"payload" => array(
"message" => array(
"text" => array(
array("role" => "user", "content" => $question)
)
)
)
);
$url = $this->makeUrl();
try{
$client = new Client($url , "ws://".$this->host , []);
// var_dump($url);
$client->connect();
$client->sendData(json_encode($data));
//$response = $client->receive();
$result = [];
//最多获取50段
for($i = 0; $i< 50; $i++) {
// $response = $client->receive()[0]->getPayload();
$res = $client->receive();
if(!isset($res[$i])){
break;
}
$response = $res[$i]->getPayload();
if(!$response){
break;
}
$response = json_decode($response, true);
Log::write($response, "ws");
$result[] = $response['payload']['choices']['text'][0]['content'];
if($response['header']['status'] == 2){
//结束了
break;
}
}
$client->disconnect();
return join("", $result);
}
catch (\Exception $e){
return $e->getMessage();
}
}
}
调用方法如下:
$Xfyun = new Xfyun();
$res = $Xfyun->send($qustion, '你能为我做什么');