import { getToken } from '@/common/common' import { get_base_url } from '@/api/request.js' import { ref, onUnmounted, computed, getCurrentInstance } from 'vue'; import { ProtocolCodec, MessageType, SerializationType, CompressionType, ControlCommand, ProtocolConst } from './ProtocolCodec'; const DEFAULT_AUTH_PARAMS = { user_id: '1001', // 默认用户ID(可从缓存/全局状态取) token: '', // 优先从缓存获取,避免硬编码 name: '测试用户', device_id: uni.getSystemInfoSync().deviceId || '', // 设备ID(补充) timestamp: Date.now() // 时间戳(防篡改) }; // const wsUrl = 'ws://127.0.0.1:8000/ws/audio' const url = '/trapractice/voiceCallSocket/voiceCall' const _baseUrl = get_base_url(url).split('http').join('ws') export default function useWebSocket(aaas = null, options = {}) { const isRecording = ref(false) //是否接通 const ws = ref(null) const initConnection = ({ authParams = {}, onStartRecord, playPcmCallback, setPlayNumber = () => {}, //设置当前播放的音频的id,用于播放完成回调 onError = () => {}, onClose = () => {}, }) => { const wsUrl = _baseUrl + url + '?summary=' + getToken() const finalAuthParams = { ...DEFAULT_AUTH_PARAMS, ...authParams, }; ws.value = uni.connectSocket({ url: wsUrl, fail: () => { // console.log('fail'); }, success: () => { // console.log('web'); } }); ws.value.onOpen((res) => { console.log('onOpen', finalAuthParams); ws.value.send({ data: ProtocolCodec.pack(MessageType.IDENTITY, finalAuthParams) }); }); ws.value.onError((err) => onError(err)) ws.value.onClose((err) => { console.log('onClose', err); onClose(err) }); ws.value.onMessage((res) => { const { msgType, body } = ProtocolCodec.unpack(res.data); switch (msgType) { case MessageType.IDENTITY: console.log('身份校验', body); onStartRecord(body) break; case MessageType.AUDIO_DATA: const buffer = body; if (buffer.byteLength < 2) break; const uint8 = new Uint8Array(buffer); const numArray = Array.from(uint8); playPcmCallback(numArray) break; case MessageType.ERROR: switch (body.errCode) { case 1: // ASR或TTS初始化出错 console.log('后端返回的错误', body.errMsg); case 4: console.log('通话接通失败', body.errMsg); // 通话接通失败,请稍后再试! ws.value.close({ code: 4001, reason: body.errMsg }) break; default: // 其他错误码的默认处理(如果需要) // ws.value.close({ // code: 1001, // reason: body.errMsg // }) break; } break; case MessageType.CONTROL_CMD: // 控制消息 console.log('控制消息', msgType, body); if (body.type === 1) { // 开始播放,记录当前播放的语音id console.log('开始播放,记录当前播放的语音id', body.lock); setPlayNumber(body.lock) } break; default: console.log('其他消息', msgType, body); break; } }); } const send = (data) => { ws.value.send({ data }); } const close = () => { ws.value.close({ code: 1000, reason: '用户挂断', success: () => { console.log('挂断success'); }, fail: () => { console.log('挂断fail'); }, complete: () => { console.log('挂断complete'); } }); } return { ws, close, initConnection, send, isRecording }; }