使用 AsyncTcpConnection 異步websocket客戶端,連接成功之后,發(fā)送文本數(shù)據(jù)沒有問題,發(fā)送二進(jìn)制數(shù)據(jù),就會到時(shí)連接關(guān)閉
# 類文件代碼
<?php
namespace plugin\webman\gateway\service;
use support\Log;
use Workerman\Connection\AsyncTcpConnection;
class TentWebsocket
{
protected string $secretId = 'xxx';
protected string $secretKey = 'xxx';
protected string $appId = 'xxx';
protected string $url;
/**
* @var null | AsyncTcpConnection
*/
protected $connect = null;
public function __construct()
{
// 當(dāng)前時(shí)間戳
$timestamp = time();
// 簽名過期時(shí)間,這里設(shè)置為當(dāng)前時(shí)間后的有效期,例如600秒
$expired = $timestamp + 3600;
// 隨機(jī)正整數(shù)
$nonce = random_int(10000000, 99999999);
$voiceId = md5(uniqid(microtime(true)));
Log::info(__METHOD__, ['voiceId' => $voiceId, 'nonce' => $nonce,
'expired' => $expired, 'secretid' => $this->secretId]);
// 將參數(shù)按照字段名的字典順序排序
$params = [
'secretid' => $this->secretId,
'timestamp' => $timestamp,
'expired' => $expired,
'nonce' => $nonce,
'engine_model_type' => '16k_zh_large',
'voice_id' => $voiceId,
'voice_format' => 1, //pcm
];
ksort($params);
// 拼接簽名原文字符串
$queryString = http_build_query($params);
//wss://
$wssUrl = "asr.cloud.tencent.com/asr/v2/{$this->appId}?{$queryString}";
// 使用HmacSha1算法生成簽名串
$signature = base64_encode(hash_hmac('sha1', $wssUrl, $this->secretKey, true));
$this->url = 'ws://' . $wssUrl . '&signature=' . urlencode($signature);
}
/**
* @return AsyncTcpConnection
* @throws \Exception
*/
public function test()
{
// 創(chuàng)建異步TCP連接
$connection = new AsyncTcpConnection($this->url);
$connection->maxSendBufferSize = 1048576 * 20;
$connection->transport = 'ssl';
return $connection;
// $connect->send('{"type":"FINISH"}');
}
}
# 進(jìn)程啟動
public static function onWorkerStart($worker)
{
error_reporting(E_ALL);
Log::info('進(jìn)程啟動:'.$worker->id);
if($worker->id === 0){
Log::info('開啟定時(shí)器');
$t = new TentWebsocket();
$audioFilePath = "/home/www/webman/public/test.pcm"; // 請?zhí)鎿Q為您的音頻文件路徑
$audioData = file_get_contents($audioFilePath);
$chunkSize = 1280; // 舉例,具體大小請參照騰訊云文檔
$totalSize = strlen($audioData);
for ($i = 0; $i < $totalSize; $i += $chunkSize) {
self::$audioDatas[] = substr($audioData, $i, $chunkSize);
}
Log::info(' count='.count(self::$audioDatas));
self::$websocket = $t->test();
self::$websocket->onWebSocketConnect = function (AsyncTcpConnection $connect, $response) {
Log::info('騰訊實(shí)時(shí)asr Connected to Tencent AI Recognition' . $response); // 這里 正常顯示了
self::$connect = $connect;
};
// 當(dāng)接收到數(shù)據(jù)時(shí)
self::$websocket->onMessage = function (AsyncTcpConnection $connect, $message) {
Log::info($message);
};
// 當(dāng)連接發(fā)生錯(cuò)誤時(shí)
self::$websocket->onError = function ($connection, $code, $message) {
Log::error('騰訊實(shí)時(shí)asr Error ' . $code . ': ' . $message);
};
// 當(dāng)連接關(guān)閉時(shí)
self::$websocket->onClose = function ($connection) {
Log::info('騰訊實(shí)時(shí)asr Connection closed'); //日志顯示 這里掉線
$connection->reConnect();
};
// 執(zhí)行連接
self::$websocket->connect();
Timer::add(0.04, function (){
if(is_null(self::$connect)){
Log::info('連接為空');
return;
}
if(self::$times>=count(self::$audioDatas)){
return;
}
$flag = self::$connect->send(self::$audioDatas[self::$times], true);
Log::info('發(fā)送音頻數(shù)據(jù):' . self::$times.'flag='.$flag.': count='.count(self::$audioDatas));
// 發(fā)送結(jié)束標(biāo)志
if (self::$times == (count(self::$audioDatas)-1)) {
Log::info('發(fā)送結(jié)束數(shù)據(jù)');
self::$connect->send('{"type":"end"}');
}
self::$times++;
});
}
}
哥們,你是怎么樣解決的,我的情況和你一樣,也是發(fā)送二進(jìn)制的話,就會自動中斷,我還去阿里云那邊確認(rèn)就是二進(jìn)制數(shù)據(jù)的問題,發(fā)送json都是正常的。是需要怎么配置?
要指定格式為二進(jìn)制,$this->connect->websocketType = Ws::BINARY_TYPE_ARRAYBUFFER;
$tempDir = BASE_PATH . '/public/audio/31.pcm';
$audioData = file_get_contents($tempDir);
if (!$audioData) {
echo "文件讀取失敗或?yàn)榭誠n";
}
self::$aliWs->websocketType = Websocket::BINARY_TYPE_ARRAYBUFFER;
$bl = self::$aliWs->send($audioData);
代碼要這樣寫就可以了。