使用 AsyncTcpConnection 异步websocket客户端,连接成功之后,发送文本数据没有问题,发送二进制数据,就会到时连接关闭
# 类文件代码
<?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()
{
// 当前时间戳
$timestamp = time();
// 签名过期时间,这里设置为当前时间后的有效期,例如600秒
$expired = $timestamp + 3600;
// 随机正整数
$nonce = random_int(10000000, 99999999);
$voiceId = md5(uniqid(microtime(true)));
Log::info(__METHOD__, ['voiceId' => $voiceId, 'nonce' => $nonce,
'expired' => $expired, 'secretid' => $this->secretId]);
// 将参数按照字段名的字典顺序排序
$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()
{
// 创建异步TCP连接
$connection = new AsyncTcpConnection($this->url);
$connection->maxSendBufferSize = 1048576 * 20;
$connection->transport = 'ssl';
return $connection;
// $connect->send('{"type":"FINISH"}');
}
}
# 进程启动
public static function onWorkerStart($worker)
{
error_reporting(E_ALL);
Log::info('进程启动:'.$worker->id);
if($worker->id === 0){
Log::info('开启定时器');
$t = new TentWebsocket();
$audioFilePath = "/home/www/webman/public/test.pcm"; // 请替换为您的音频文件路径
$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('腾讯实时asr Connected to Tencent AI Recognition' . $response); // 这里 正常显示了
self::$connect = $connect;
};
// 当接收到数据时
self::$websocket->onMessage = function (AsyncTcpConnection $connect, $message) {
Log::info($message);
};
// 当连接发生错误时
self::$websocket->onError = function ($connection, $code, $message) {
Log::error('腾讯实时asr Error ' . $code . ': ' . $message);
};
// 当连接关闭时
self::$websocket->onClose = function ($connection) {
Log::info('腾讯实时asr Connection closed'); //日志显示 这里掉线
$connection->reConnect();
};
// 执行连接
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('发送音频数据:' . self::$times.'flag='.$flag.': count='.count(self::$audioDatas));
// 发送结束标志
if (self::$times == (count(self::$audioDatas)-1)) {
Log::info('发送结束数据');
self::$connect->send('{"type":"end"}');
}
self::$times++;
});
}
}
哥们,你是怎么样解决的,我的情况和你一样,也是发送二进制的话,就会自动中断,我还去阿里云那边确认就是二进制数据的问题,发送json都是正常的。是需要怎么配置?
要指定格式为二进制,$this->connect->websocketType = Ws::BINARY_TYPE_ARRAYBUFFER;