|
|
@@ -51,15 +51,21 @@ const getWebSocketUrl = (customUrl?: string): string => {
|
|
|
}
|
|
|
} else {
|
|
|
// 自动协议检测
|
|
|
- const isHttps = window.location.protocol === 'https:';
|
|
|
- const protocol = isHttps ? 'wss:' : 'ws:';
|
|
|
const hostname = window.location.hostname;
|
|
|
|
|
|
- // 根据协议选择端口
|
|
|
- const defaultPort = isHttps ? '8766' : '8765';
|
|
|
- const port = process.env.REACT_APP_WS_PORT || defaultPort;
|
|
|
-
|
|
|
- baseUrl = `${protocol}//${hostname}:${port}`;
|
|
|
+ // 在localhost开发环境中强制使用WS协议
|
|
|
+ if (hostname === 'localhost' || hostname === '127.0.0.1') {
|
|
|
+ const protocol = 'ws:';
|
|
|
+ const port = process.env.REACT_APP_WS_PORT || '8765';
|
|
|
+ baseUrl = `${protocol}//${hostname}:${port}`;
|
|
|
+ } else {
|
|
|
+ // 生产环境使用HTTPS检测
|
|
|
+ const isHttps = window.location.protocol === 'https:';
|
|
|
+ const protocol = isHttps ? 'wss:' : 'ws:';
|
|
|
+ const defaultPort = isHttps ? '8766' : '8765';
|
|
|
+ const port = process.env.REACT_APP_WS_PORT || defaultPort;
|
|
|
+ baseUrl = `${protocol}//${hostname}:${port}`;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -113,7 +119,7 @@ export const useWebSocket = (options: UseWebSocketOptions = {}) => {
|
|
|
wsRef.current.onAudioResponse(options.onAudioResponse);
|
|
|
console.log('[useWebSocket] 音频响应回调已设置');
|
|
|
}
|
|
|
- wsRef.current.onOpen(() => {
|
|
|
+ wsRef.current.onOpen(async () => {
|
|
|
console.log('useWebSocket: WebSocket连接已建立,设置状态为已连接');
|
|
|
connectingRef.current = false; // 重置连接状态
|
|
|
dispatch(setConnected(true));
|
|
|
@@ -124,6 +130,17 @@ export const useWebSocket = (options: UseWebSocketOptions = {}) => {
|
|
|
clearTimeout(errorTimeoutRef.current);
|
|
|
errorTimeoutRef.current = null;
|
|
|
}
|
|
|
+
|
|
|
+ // 自动发送会话初始化消息
|
|
|
+ try {
|
|
|
+ console.log('[useWebSocket] 自动发送会话初始化消息');
|
|
|
+ await wsRef.current?.sendMessage({
|
|
|
+ type: 'session_init',
|
|
|
+ timestamp: Date.now() / 1000,
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ console.error('[useWebSocket] 发送会话初始化消息失败:', error);
|
|
|
+ }
|
|
|
});
|
|
|
|
|
|
wsRef.current.onClose(() => {
|
|
|
@@ -164,30 +181,50 @@ export const useWebSocket = (options: UseWebSocketOptions = {}) => {
|
|
|
|
|
|
switch (message.type) {
|
|
|
case 'session_init_response':
|
|
|
- if (message.data?.session_id) {
|
|
|
- dispatch(setSession(message.data.session_id));
|
|
|
- console.log('[useWebSocket] 会话已初始化:', message.data.session_id);
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
- case 'latency_response':
|
|
|
- if (typeof message.data?.latency === 'number') {
|
|
|
- dispatch(setLatency(message.data.latency));
|
|
|
- }
|
|
|
- break;
|
|
|
-
|
|
|
case 'session_init':
|
|
|
console.log('[useWebSocket] 收到会话初始化响应:', message);
|
|
|
- if (message.session_id) {
|
|
|
- dispatch(setSession({
|
|
|
+ // 处理会话初始化响应
|
|
|
+ let sessionData;
|
|
|
+
|
|
|
+ // 优先检查直接在消息中的格式(当前后端使用的格式)
|
|
|
+ if (message.session_id && message.success) {
|
|
|
+ sessionData = {
|
|
|
id: message.session_id,
|
|
|
userId: message.user_id,
|
|
|
language: message.language || 'zh-CN',
|
|
|
startTime: Date.now(),
|
|
|
lastActivity: Date.now(),
|
|
|
isActive: true,
|
|
|
- }));
|
|
|
- console.log('[useWebSocket] 会话状态已更新到Redux');
|
|
|
+ };
|
|
|
+ console.log('[useWebSocket] 使用直接格式创建会话数据:', sessionData);
|
|
|
+
|
|
|
+ } else if (message.data?.session_id) {
|
|
|
+ // 备选格式:使用data字段
|
|
|
+ sessionData = {
|
|
|
+ id: message.data.session_id,
|
|
|
+ userId: message.data.user_id,
|
|
|
+ language: message.data.language || 'zh-CN',
|
|
|
+ startTime: Date.now(),
|
|
|
+ lastActivity: Date.now(),
|
|
|
+ isActive: true,
|
|
|
+ };
|
|
|
+ console.log('[useWebSocket] 使用data字段格式创建会话数据:', sessionData);
|
|
|
+ } else {
|
|
|
+ console.warn('[useWebSocket] 会话初始化响应格式不正确:', message);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sessionData) {
|
|
|
+ dispatch(setSession(sessionData));
|
|
|
+ dispatch(setConnectionStatus('connected'));
|
|
|
+ console.log('[useWebSocket] 会话状态已更新到Redux:', sessionData);
|
|
|
+ } else {
|
|
|
+ console.error('[useWebSocket] 无法创建会话数据,消息格式:', message);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'latency_response':
|
|
|
+ if (typeof message.data?.latency === 'number') {
|
|
|
+ dispatch(setLatency(message.data.latency));
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
@@ -278,6 +315,21 @@ export const useWebSocket = (options: UseWebSocketOptions = {}) => {
|
|
|
}
|
|
|
}, [isConnected]);
|
|
|
|
|
|
+ // 发送原始PCM音频数据(跳过转换)
|
|
|
+ const sendRawPCMAudio = useCallback(async (pcmData: Int16Array, isFinal: boolean = false) => {
|
|
|
+ if (!wsRef.current || !isConnected) {
|
|
|
+ throw new Error('WebSocket未连接');
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 直接发送原始PCM数据
|
|
|
+ await wsRef.current.sendRawPCMAudioData(pcmData, isFinal);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('发送原始PCM音频失败:', error);
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
+ }, [isConnected]);
|
|
|
+
|
|
|
// 开始会话
|
|
|
const startSession = useCallback(async (language: string = 'zh-CN') => {
|
|
|
const message: WebSocketMessage = {
|
|
|
@@ -342,6 +394,7 @@ export const useWebSocket = (options: UseWebSocketOptions = {}) => {
|
|
|
sendMessage,
|
|
|
sendAudioData,
|
|
|
sendAudioBlob,
|
|
|
+ sendRawPCMAudio,
|
|
|
startSession,
|
|
|
endSession,
|
|
|
resetChunkCounter,
|