SmartMeeting/speakr/static/js/wsconnecter copy.js

316 lines
8.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
* Reserved. MIT License (https://opensource.org/licenses/MIT)
*/
/* 2021-2023 by zhaoming,mali aihealthx.com */
let isfilemode = false;
let configwords = "";
let wssBaseUrl={};
//------------------- WebSocket 配置初始化 start------------------
async function init() {
// 在这里请求接口
wssBaseUrl = await getBaseUrlFromApi();
console.log(wssBaseUrl, "获取baseUrl");
}
// 示例:请求接口获取 baseUrl
async function getBaseUrlFromApi() {
try {
const response = await fetch(
`getUserConfig`,
{
method: "GET",
}
);
if (!response.ok) {
throw new Error("请求失败");
}
const data = await response.json();
configwords = data
return configwords;
} catch (error) {
console.error("获取 configwords 出错:", error);
}
}
// 初始化程序入口
init();
console.log("进入ws");
//--------------------WebSocket 配置初始化 end------------------
//------------------- FunASR WebSocket 连接器 start------------------
function WebSocketConnectMethod(config) {
//定义socket连接方法类
var speechSokt;
var connKeeperID;
var msgHandle = config.msgHandle;
var stateHandle = config.stateHandle;
let modeType = "offline";
// 发送队列和流量控制
var sendQueue = [];
var isSending = false;
var maxQueueSize = 1000; // 最大队列长度,防止内存溢出
var queueWarningThreshold = 500; // 队列警告阈值
var lastDisconnWarnTime = 0; // WebSocket未连接警告节流
function trimQueueIfNeeded() {
if (sendQueue.length <= maxQueueSize) {
return false;
}
const dropCount = sendQueue.length - maxQueueSize;
console.warn(
`⚠️ 发送队列超过最大限制 (${maxQueueSize}),丢弃最旧的 ${dropCount} 个数据包`
);
sendQueue = sendQueue.slice(-maxQueueSize);
return true;
}
function enqueueData(data) {
sendQueue.push(data);
trimQueueIfNeeded();
if (sendQueue.length > queueWarningThreshold) {
console.warn(`⚠️ WebSocket发送队列堆积: ${sendQueue.length} 个数据包待发送`);
}
}
this.wsStart = function (e) {
if (speechSokt) {
speechSokt.close();
}
//------------------- FunASR 连接模式选择 start------------------
// app.js 中 rec 和 rec2 可能连接同一个 /websocket_offline 地址。
// online/offline 的区别不靠 URL而靠 onOpen() 握手 JSON 中的 mode 字段:
// wsStart() 不传参数 => mode:"online"; wsStart(url) 传参 => mode:"offline"。
var Uri = e ? e : `wss://${wssBaseUrl.FUNASR_WEBSOCKET_IP}/websocket_offline`;
if (e) {
modeType = "offline";
} else {
modeType = "online";
}
//--------------------FunASR 连接模式选择 end------------------
if (Uri.match(/wss:\S*|ws:\S*/)) {
console.log("Uri" + Uri);
} else {
alert("请检查wss地址正确性");
return 0;
}
if ("WebSocket" in window) {
speechSokt = new WebSocket(Uri); // 定义socket连接对象
speechSokt.onopen = function (e) {
onOpen(e);
}; // 定义响应函数
speechSokt.onclose = function (e) {
console.log("onclose ws!");
//speechSokt.close();
onClose(e);
};
speechSokt.onmessage = function (e) {
onMessage(e);
};
speechSokt.onerror = function (e) {
onError(e);
};
return 1;
} else {
alert("当前浏览器不支持 WebSocket");
return 0;
}
};
// 定义停止与发送函数
this.wsStop = function () {
if (speechSokt != undefined) {
console.log("stop ws!");
speechSokt.close();
}
// 清空发送队列
sendQueue = [];
isSending = false;
};
// 处理发送队列
function processQueue() {
if (
isSending ||
sendQueue.length === 0 ||
!speechSokt ||
speechSokt.readyState !== 1
) {
return;
}
isSending = true;
const data = sendQueue.shift();
try {
speechSokt.send(data);
isSending = false;
// 队列警告
if (sendQueue.length > queueWarningThreshold) {
console.warn(`⚠️ WebSocket发送队列堆积: ${sendQueue.length} 个数据包待发送`);
}
// 继续处理队列
if (sendQueue.length > 0) {
// 使用 setTimeout 避免阻塞
setTimeout(() => processQueue(), 0);
}
} catch (e) {
console.error("❌ WebSocket发送失败数据已放回队列:", e);
sendQueue.unshift(data); // 放回队列头部
isSending = false;
trimQueueIfNeeded();
}
}
this.wsSend = function (oneData) {
if (speechSokt == undefined) {
// WebSocket未初始化缓存数据
enqueueData(oneData);
return true;
}
if (speechSokt.readyState === 1) {
// WebSocket已打开
if (sendQueue.length > 0) {
// 队列中有数据,先加入队列
enqueueData(oneData);
processQueue();
return true;
} else {
// 队列为空,尝试直接发送
try {
speechSokt.send(oneData);
return true;
} catch (e) {
console.error("❌ WebSocket直接发送失败加入队列:", e);
enqueueData(oneData);
processQueue();
return true;
}
}
} else if (speechSokt.readyState === 0) {
// WebSocket正在连接缓存数据
enqueueData(oneData);
return true;
} else {
// WebSocket已关闭或关闭中丢弃数据并警告节流 5 秒)
var now = Date.now();
if (now - lastDisconnWarnTime > 5000) {
console.warn("⚠️ WebSocket未连接数据无法发送 (state:", speechSokt.readyState, ")");
lastDisconnWarnTime = now;
}
return false;
}
};
// 获取队列状态(用于调试)
this.getQueueStatus = function () {
return {
length: sendQueue.length,
isSending: isSending,
readyState: speechSokt ? speechSokt.readyState : -1
};
};
async function getBaseHot(params) {
try {
const response = await fetch(`/tool/speakr/api/hotwords`, {
method: "GET",
});
if (!response.ok) {
// 请求失败时返回空
console.warn("getBaseHot 请求失败,使用默认 hotwords");
return "{}";
}
const data = await response.json();
const resultObj = data.hotwords.reduce((obj, item) => {
obj[item.keyword] = item.weight;
return obj;
}, {});
return JSON.stringify(resultObj);
} catch (err) {
// 发生异常时返回空
console.error("getBaseHot 调用出错:", err);
return "";
}
}
// SOCEKT连接中的消息与状态响应
async function onOpen(e) {
console.log(e, "e");
// 发送json
var chunk_size = new Array(10, 10, 10);
var request = {
chunk_size: chunk_size,
wav_name: "h5",
is_speaking: true,
chunk_interval: 10,
itn: true, // 是否使用ITN
// "mode":"2pass",// 模型模式
// 对应 app.js 的 rec/rec2 双链路:同地址下通过 mode 区分在线预览和离线正式结果。
mode: modeType,
hotwords: await getBaseHot(),
};
console.log(request, "request");
if (isfilemode) {
request.wav_format = file_ext;
if (file_ext == "wav") {
request.wav_format = "PCM";
request.audio_fs = file_sample_rate;
}
}
// var hotwords=getBaseHot();
// console.log(hotwords);
// if(hotwords!=null )
// {
// request.hotwords=hotwords;
// }
// console.log(JSON.stringify(request),'热词');
speechSokt.send(JSON.stringify(request));
console.log("连接成功");
stateHandle(0);
// 连接成功后,处理队列中积压的数据
if (sendQueue.length > 0) {
console.log(`📤 处理连接前积压的 ${sendQueue.length} 个数据包`);
processQueue();
}
}
function onClose(e) {
stateHandle(1);
}
function onMessage(e) {
msgHandle(e);
}
function onError(e) {
// info_div.innerHTML="连接"+e;
console.log(e);
stateHandle(2);
}
//--------------------FunASR WebSocket 连接器 end------------------
}