【m】聊天消息接入
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
import store from './store.js';
|
||||
import UIRenderer from './renderer.js';
|
||||
import apiClient from './api.js';
|
||||
import wsManager from './websocket.js';
|
||||
// import wsManager from './websocket.js';
|
||||
import { mockCallSession } from './models.js';
|
||||
import { showNotification, generateId } from './utils.js';
|
||||
|
||||
@@ -39,75 +39,75 @@ let connectionId = "";
|
||||
* 绑定WebSocket事件
|
||||
*/
|
||||
function bindWebSocketEvents() {
|
||||
wsManager.on('connect', () => {
|
||||
console.log('WebSocket connected');
|
||||
showNotification('已连接到服务器');
|
||||
});
|
||||
// wsManager.on('connect', () => {
|
||||
// console.log('WebSocket connected');
|
||||
// showNotification('已连接到服务器');
|
||||
// });
|
||||
|
||||
wsManager.on('disconnect', () => {
|
||||
console.log('WebSocket disconnected');
|
||||
showNotification('与服务器的连接已断开', 5000);
|
||||
});
|
||||
// wsManager.on('disconnect', () => {
|
||||
// console.log('WebSocket disconnected');
|
||||
// showNotification('与服务器的连接已断开', 5000);
|
||||
// });
|
||||
|
||||
wsManager.on('message-received', (data) => {
|
||||
console.log('Message received:', data);
|
||||
store.addMessage(data.message);
|
||||
});
|
||||
// wsManager.on('message-received', (data) => {
|
||||
// console.log('Message received:', data);
|
||||
// store.addMessage(data.message);
|
||||
// });
|
||||
|
||||
wsManager.on('user-joined', (data) => {
|
||||
console.log('User joined:', data);
|
||||
showNotification(`${data.userId} 加入了通话`);
|
||||
});
|
||||
// wsManager.on('user-joined', (data) => {
|
||||
// console.log('User joined:', data);
|
||||
// showNotification(`${data.userId} 加入了通话`);
|
||||
// });
|
||||
|
||||
wsManager.on('user-left', (data) => {
|
||||
console.log('User left:', data);
|
||||
showNotification(`${data.userId} 离开了通话`);
|
||||
});
|
||||
// wsManager.on('user-left', (data) => {
|
||||
// console.log('User left:', data);
|
||||
// showNotification(`${data.userId} 离开了通话`);
|
||||
// });
|
||||
|
||||
wsManager.on('media-state-changed', (data) => {
|
||||
console.log('Media state changed:', data);
|
||||
// 更新远端媒体状态
|
||||
if (data.userId !== store.getLocalUser().id) {
|
||||
store.updateRemoteMedia(data);
|
||||
}
|
||||
});
|
||||
// wsManager.on('media-state-changed', (data) => {
|
||||
// console.log('Media state changed:', data);
|
||||
// // 更新远端媒体状态
|
||||
// if (data.userId !== store.getLocalUser().id) {
|
||||
// store.updateRemoteMedia(data);
|
||||
// }
|
||||
// });
|
||||
|
||||
wsManager.on('network-quality', (data) => {
|
||||
console.log('Network quality changed:', data);
|
||||
// 更新网络质量
|
||||
const state = store.getState();
|
||||
if (data.userId === state.session.remoteUser.id) {
|
||||
state.session.remoteUser.networkQuality = data.quality;
|
||||
store.notify({ type: 'NETWORK_CHANGE', quality: data.quality });
|
||||
}
|
||||
});
|
||||
// wsManager.on('network-quality', (data) => {
|
||||
// console.log('Network quality changed:', data);
|
||||
// // 更新网络质量
|
||||
// const state = store.getState();
|
||||
// if (data.userId === state.session.remoteUser.id) {
|
||||
// state.session.remoteUser.networkQuality = data.quality;
|
||||
// store.notify({ type: 'NETWORK_CHANGE', quality: data.quality });
|
||||
// }
|
||||
// });
|
||||
|
||||
wsManager.on('call-ended', (data) => {
|
||||
console.log('Call ended:', data);
|
||||
store.endCall();
|
||||
showNotification('通话已结束', 3000);
|
||||
});
|
||||
// wsManager.on('call-ended', (data) => {
|
||||
// console.log('Call ended:', data);
|
||||
// store.endCall();
|
||||
// showNotification('通话已结束', 3000);
|
||||
// });
|
||||
|
||||
wsManager.on('call-request', (data) => {
|
||||
console.log('Call request received:', data);
|
||||
// 显示通话请求弹窗
|
||||
if (window.showCallRequest) {
|
||||
const caller = {
|
||||
name: mockCallSession.remoteUser.name,
|
||||
avatar: mockCallSession.remoteUser.avatar
|
||||
};
|
||||
window.showCallRequest(caller);
|
||||
connectionId = data.connectionId;
|
||||
}
|
||||
});
|
||||
//处理发送消息响应
|
||||
wsManager.on('chat-message', (data) => {
|
||||
console.log('chat-message:', data);
|
||||
// 显示消息
|
||||
store.addMessage({
|
||||
data: data.message,
|
||||
});
|
||||
});
|
||||
// wsManager.on('call-request', (data) => {
|
||||
// console.log('Call request received:', data);
|
||||
// // 显示通话请求弹窗
|
||||
// if (window.showCallRequest) {
|
||||
// const caller = {
|
||||
// name: mockCallSession.remoteUser.name,
|
||||
// avatar: mockCallSession.remoteUser.avatar
|
||||
// };
|
||||
// window.showCallRequest(caller);
|
||||
// connectionId = data.connectionId;
|
||||
// }
|
||||
// });
|
||||
// //处理发送消息响应
|
||||
// wsManager.on('chat-message', (data) => {
|
||||
// console.log('chat-message:', data);
|
||||
// // 显示消息
|
||||
// store.addMessage({
|
||||
// data: data.message,
|
||||
// });
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,8 +216,8 @@ function bindDomEvents() {
|
||||
|
||||
if (content) {
|
||||
const state = store.getState();
|
||||
const newMessage = {
|
||||
id: generateId(),
|
||||
const message = {
|
||||
id: state.id,
|
||||
senderId: state.session.localUser.id,
|
||||
senderName: state.session.localUser.name,
|
||||
senderAvatar: state.session.localUser.avatar,
|
||||
@@ -227,14 +227,25 @@ function bindDomEvents() {
|
||||
isSelf: true
|
||||
};
|
||||
|
||||
store.addMessage(newMessage);
|
||||
chatInput.value = '';
|
||||
const message = {
|
||||
connectionId: connectionId,
|
||||
message: newMessage
|
||||
store.addMessage(message);
|
||||
|
||||
|
||||
const newMessage = {
|
||||
id: state.id,
|
||||
senderId: state.session.remoteUser.id,
|
||||
senderName: state.session.remoteUser.name,
|
||||
senderAvatar: state.session.remoteUser.avatar,
|
||||
content: content,
|
||||
type: 'text',
|
||||
timestamp: new Date().toISOString(),
|
||||
isSelf: false
|
||||
|
||||
};
|
||||
chatInput.value = '';
|
||||
// 发送消息到服务器
|
||||
wsManager.send('chat-message', message);
|
||||
store.sendChatMessage(newMessage);
|
||||
|
||||
//wsManager.send('chat-message', message);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -367,4 +378,4 @@ window.addEventListener('DOMContentLoaded', async () => {
|
||||
});
|
||||
|
||||
// 导出全局变量
|
||||
export { store, renderer, apiClient, wsManager };
|
||||
export { store, renderer, apiClient };
|
||||
|
||||
@@ -6,13 +6,14 @@ import { mockCallSession, mockMessages } from './models.js';
|
||||
import { Signaling, WebSocketSignaling } from "../../module/signaling.js";// 信令管理
|
||||
import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理
|
||||
import { getServerConfig, getRTCConfiguration } from "../js/config.js";//服务器配置和RTC配置
|
||||
import { showNotification } from './utils.js'; // 导入通知函数
|
||||
import { showNotification, generateId } from './utils.js'; // 导入通知函数
|
||||
// 默认视频流尺寸
|
||||
const defaultStreamWidth = 1280;
|
||||
const defaultStreamHeight = 720;
|
||||
|
||||
|
||||
|
||||
|
||||
class CallStateManager {
|
||||
constructor() {
|
||||
const renderstreaming = null; // WebRTC连接管理实例
|
||||
@@ -20,6 +21,7 @@ class CallStateManager {
|
||||
const connectionId = null; // 连接ID
|
||||
// 核心状态
|
||||
this.state = {
|
||||
id: generateId(),
|
||||
session: {
|
||||
...mockCallSession,
|
||||
status: 'idle' // 初始状态为空闲
|
||||
@@ -255,6 +257,7 @@ class CallStateManager {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置WebRTC连接
|
||||
* @async
|
||||
@@ -362,7 +365,17 @@ class CallStateManager {
|
||||
}
|
||||
}
|
||||
};
|
||||
// 初始化 RenderStreaming 实例后
|
||||
this.renderstreaming.onMessage = (data) => {
|
||||
console.log('收到聊天消息:', data);
|
||||
if (data.type === 'chat-message') {
|
||||
// 处理聊天消息
|
||||
// 添加到消息列表并更新UI
|
||||
store.addMessage(data.message);
|
||||
} else if (data.type === 'on-message') {
|
||||
}
|
||||
|
||||
};
|
||||
// 启动WebRTC连接
|
||||
await this.renderstreaming.start();
|
||||
await this.renderstreaming.createConnection(connectionId);
|
||||
@@ -454,7 +467,15 @@ class CallStateManager {
|
||||
|
||||
this.notify({ type: 'NEW_MESSAGE', message, unreadCount: this.state.unreadCount });
|
||||
}
|
||||
sendChatMessage(message) {
|
||||
if (this.renderstreaming) {
|
||||
|
||||
this.renderstreaming.sendMessage({
|
||||
type: 'chat-message',
|
||||
message: message,
|
||||
});
|
||||
}
|
||||
}
|
||||
// 切换侧边栏
|
||||
toggleSidebar() {
|
||||
this.state.isSidebarOpen = !this.state.isSidebarOpen;
|
||||
@@ -595,7 +616,7 @@ class CallStateManager {
|
||||
console.error('Error detecting network quality:', error);
|
||||
}
|
||||
}
|
||||
// 真实音频活动检测 - 远端
|
||||
// 真实音频活动检测 - 远端
|
||||
startRemoteActivityDetection() {
|
||||
// 检查是否有远端音频流
|
||||
if (!this.state.remoteStream) {
|
||||
|
||||
@@ -1,303 +1,303 @@
|
||||
/**
|
||||
* WebSocket管理
|
||||
* 管理WebSocket连接,处理WebSocket事件
|
||||
*/
|
||||
import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理
|
||||
// /**
|
||||
// * WebSocket管理
|
||||
// * 管理WebSocket连接,处理WebSocket事件
|
||||
// */
|
||||
// import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理
|
||||
|
||||
class WebSocketManager {
|
||||
constructor() {
|
||||
this.isConnected = false;
|
||||
}
|
||||
// class WebSocketManager {
|
||||
// constructor() {
|
||||
// this.isConnected = false;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取默认WebSocket URL
|
||||
* @returns {string} WebSocket URL
|
||||
*/
|
||||
getDefaultWebSocketUrl() {
|
||||
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
return `${protocol}//${location.host}`;
|
||||
}
|
||||
// /**
|
||||
// * 获取默认WebSocket URL
|
||||
// * @returns {string} WebSocket URL
|
||||
// */
|
||||
// getDefaultWebSocketUrl() {
|
||||
// const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
// return `${protocol}//${location.host}`;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 连接WebSocket
|
||||
*/
|
||||
init() {
|
||||
try {
|
||||
// /**
|
||||
// * 连接WebSocket
|
||||
// */
|
||||
// init() {
|
||||
// try {
|
||||
|
||||
RenderStreaming.onConnect = () => {
|
||||
console.log('WebSocket connected');
|
||||
this.isConnected = true;
|
||||
// RenderStreaming.onConnect = () => {
|
||||
// console.log('WebSocket connected');
|
||||
// this.isConnected = true;
|
||||
|
||||
|
||||
|
||||
// // 发送连接消息
|
||||
// this.sendConnectMessage();
|
||||
// // // 发送连接消息
|
||||
// // this.sendConnectMessage();
|
||||
|
||||
// // 启动心跳
|
||||
this.startHeartbeat();
|
||||
// // // 启动心跳
|
||||
// this.startHeartbeat();
|
||||
|
||||
// this.emit('connect');
|
||||
};
|
||||
// // this.emit('connect');
|
||||
// };
|
||||
|
||||
RenderStreaming.onDisconnect = () => {
|
||||
console.log('WebSocket disconnected');
|
||||
this.isConnected = false;
|
||||
this.stopHeartbeat();
|
||||
//this.emit('disconnect');
|
||||
//this.attemptReconnect();
|
||||
};
|
||||
// RenderStreaming.onDisconnect = () => {
|
||||
// console.log('WebSocket disconnected');
|
||||
// this.isConnected = false;
|
||||
// this.stopHeartbeat();
|
||||
// //this.emit('disconnect');
|
||||
// //this.attemptReconnect();
|
||||
// };
|
||||
|
||||
RenderStreaming.onmessage = (event) => {
|
||||
try {
|
||||
const message = JSON.parse(event.data);
|
||||
this.handleMessage(message);
|
||||
} catch (error) {
|
||||
console.error('Error parsing WebSocket message:', error);
|
||||
}
|
||||
};
|
||||
// RenderStreaming.onmessage = (event) => {
|
||||
// try {
|
||||
// const message = JSON.parse(event.data);
|
||||
// this.handleMessage(message);
|
||||
// } catch (error) {
|
||||
// console.error('Error parsing WebSocket message:', error);
|
||||
// }
|
||||
// };
|
||||
|
||||
this.socket.onerror = (error) => {
|
||||
console.error('WebSocket error:', error);
|
||||
this.emit('error', error);
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error connecting to WebSocket:', error);
|
||||
this.emit('error', error);
|
||||
}
|
||||
}
|
||||
// this.socket.onerror = (error) => {
|
||||
// console.error('WebSocket error:', error);
|
||||
// this.emit('error', error);
|
||||
// };
|
||||
// } catch (error) {
|
||||
// console.error('Error connecting to WebSocket:', error);
|
||||
// this.emit('error', error);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 断开WebSocket连接
|
||||
*/
|
||||
disconnect() {
|
||||
if (this.socket) {
|
||||
this.socket.close();
|
||||
this.socket = null;
|
||||
this.isConnected = false;
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 断开WebSocket连接
|
||||
// */
|
||||
// disconnect() {
|
||||
// if (this.socket) {
|
||||
// this.socket.close();
|
||||
// this.socket = null;
|
||||
// this.isConnected = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
* @param {string} type - 消息类型
|
||||
* @param {Object} data - 消息数据
|
||||
*/
|
||||
send(type, data) {
|
||||
if (this.isConnected && this.socket) {
|
||||
try {
|
||||
let message;
|
||||
// /**
|
||||
// * 发送消息
|
||||
// * @param {string} type - 消息类型
|
||||
// * @param {Object} data - 消息数据
|
||||
// */
|
||||
// send(type, data) {
|
||||
// if (this.isConnected && this.socket) {
|
||||
// try {
|
||||
// let message;
|
||||
|
||||
// 根据消息类型构建不同的消息格式
|
||||
if (type === 'connect' || type === 'disconnect') {
|
||||
message = JSON.stringify({ type, connectionId: this.connectionId });
|
||||
} else if (type === 'offer' || type === 'answer' || type === 'candidate') {
|
||||
message = JSON.stringify({ type, data });
|
||||
} else if (type === 'broadcast') {
|
||||
message = JSON.stringify({ type, message: data.message, targetConnectionId: data.targetConnectionId });
|
||||
} else if (type === 'ping' || type === 'pong') {
|
||||
message = JSON.stringify({ type });
|
||||
} else {
|
||||
// 兼容旧格式,用于自定义事件
|
||||
message = JSON.stringify({ event: type, data });
|
||||
}
|
||||
// // 根据消息类型构建不同的消息格式
|
||||
// if (type === 'connect' || type === 'disconnect') {
|
||||
// message = JSON.stringify({ type, connectionId: this.connectionId });
|
||||
// } else if (type === 'offer' || type === 'answer' || type === 'candidate') {
|
||||
// message = JSON.stringify({ type, data });
|
||||
// } else if (type === 'broadcast') {
|
||||
// message = JSON.stringify({ type, message: data.message, targetConnectionId: data.targetConnectionId });
|
||||
// } else if (type === 'ping' || type === 'pong') {
|
||||
// message = JSON.stringify({ type });
|
||||
// } else {
|
||||
// // 兼容旧格式,用于自定义事件
|
||||
// message = JSON.stringify({ event: type, data });
|
||||
// }
|
||||
|
||||
this.socket.send(message);
|
||||
} catch (error) {
|
||||
console.error('Error sending WebSocket message:', error);
|
||||
}
|
||||
} else {
|
||||
console.warn('WebSocket not connected, cannot send message');
|
||||
}
|
||||
}
|
||||
// this.socket.send(message);
|
||||
// } catch (error) {
|
||||
// console.error('Error sending WebSocket message:', error);
|
||||
// }
|
||||
// } else {
|
||||
// console.warn('WebSocket not connected, cannot send message');
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 处理接收到的消息
|
||||
* @param {Object} message - 消息对象
|
||||
*/
|
||||
handleMessage(message) {
|
||||
if (message.type) {
|
||||
console.log('Received message:', message);
|
||||
switch (message.type) {
|
||||
case 'user-joined':
|
||||
this.emit('user-joined', message.data);
|
||||
break;
|
||||
case 'user-left':
|
||||
this.emit('user-left', message.data);
|
||||
break;
|
||||
case 'media-state-changed':
|
||||
this.emit('media-state-changed', message.data);
|
||||
break;
|
||||
case 'message-received':
|
||||
this.emit('message-received', message.data);
|
||||
break;
|
||||
case 'network-quality':
|
||||
this.emit('network-quality', message.data);
|
||||
break;
|
||||
case 'call-ended':
|
||||
this.emit('call-ended', message.data);
|
||||
break;
|
||||
case 'call-request':
|
||||
this.emit('call-request', message.data);
|
||||
break;
|
||||
case 'ping':
|
||||
// 处理心跳请求,回复pong
|
||||
this.send('pong');
|
||||
break;
|
||||
case 'pong':
|
||||
// 处理心跳响应
|
||||
this.emit('pong');
|
||||
break;
|
||||
case 'offer':
|
||||
this.emit('offer', message.data);
|
||||
break;
|
||||
case 'answer':
|
||||
this.emit('answer', message.data);
|
||||
break;
|
||||
case 'candidate':
|
||||
this.emit('candidate', message.data);
|
||||
break;
|
||||
case 'chat-message':
|
||||
this.emit('chat-message', message.data);
|
||||
break;
|
||||
default:
|
||||
// 处理旧格式消息
|
||||
if (message.event) {
|
||||
this.emit(message.event, message.data);
|
||||
} else {
|
||||
this.emit('message', message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (message.event) {
|
||||
// 处理旧格式消息
|
||||
this.emit(message.event, message.data);
|
||||
} else {
|
||||
this.emit('message', message);
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 处理接收到的消息
|
||||
// * @param {Object} message - 消息对象
|
||||
// */
|
||||
// handleMessage(message) {
|
||||
// if (message.type) {
|
||||
// console.log('Received message:', message);
|
||||
// switch (message.type) {
|
||||
// case 'user-joined':
|
||||
// this.emit('user-joined', message.data);
|
||||
// break;
|
||||
// case 'user-left':
|
||||
// this.emit('user-left', message.data);
|
||||
// break;
|
||||
// case 'media-state-changed':
|
||||
// this.emit('media-state-changed', message.data);
|
||||
// break;
|
||||
// case 'message-received':
|
||||
// this.emit('message-received', message.data);
|
||||
// break;
|
||||
// case 'network-quality':
|
||||
// this.emit('network-quality', message.data);
|
||||
// break;
|
||||
// case 'call-ended':
|
||||
// this.emit('call-ended', message.data);
|
||||
// break;
|
||||
// case 'call-request':
|
||||
// this.emit('call-request', message.data);
|
||||
// break;
|
||||
// case 'ping':
|
||||
// // 处理心跳请求,回复pong
|
||||
// this.send('pong');
|
||||
// break;
|
||||
// case 'pong':
|
||||
// // 处理心跳响应
|
||||
// this.emit('pong');
|
||||
// break;
|
||||
// case 'offer':
|
||||
// this.emit('offer', message.data);
|
||||
// break;
|
||||
// case 'answer':
|
||||
// this.emit('answer', message.data);
|
||||
// break;
|
||||
// case 'candidate':
|
||||
// this.emit('candidate', message.data);
|
||||
// break;
|
||||
// case 'chat-message':
|
||||
// this.emit('chat-message', message.data);
|
||||
// break;
|
||||
// default:
|
||||
// // 处理旧格式消息
|
||||
// if (message.event) {
|
||||
// this.emit(message.event, message.data);
|
||||
// } else {
|
||||
// this.emit('message', message);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// } else if (message.event) {
|
||||
// // 处理旧格式消息
|
||||
// this.emit(message.event, message.data);
|
||||
// } else {
|
||||
// this.emit('message', message);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 尝试重连
|
||||
*/
|
||||
attemptReconnect() {
|
||||
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||
this.reconnectAttempts++;
|
||||
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
||||
// /**
|
||||
// * 尝试重连
|
||||
// */
|
||||
// attemptReconnect() {
|
||||
// if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
||||
// this.reconnectAttempts++;
|
||||
// const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
||||
|
||||
console.log(`Attempting to reconnect in ${delay}ms...`);
|
||||
// console.log(`Attempting to reconnect in ${delay}ms...`);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log(`Reconnect attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
|
||||
this.connect();
|
||||
}, delay);
|
||||
} else {
|
||||
console.error('Max reconnect attempts reached');
|
||||
this.emit('reconnect-failed');
|
||||
}
|
||||
}
|
||||
// setTimeout(() => {
|
||||
// console.log(`Reconnect attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
|
||||
// this.connect();
|
||||
// }, delay);
|
||||
// } else {
|
||||
// console.error('Max reconnect attempts reached');
|
||||
// this.emit('reconnect-failed');
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 生成连接ID
|
||||
* @returns {string} 连接ID
|
||||
*/
|
||||
generateConnectionId() {
|
||||
return 'conn_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
||||
}
|
||||
// /**
|
||||
// * 生成连接ID
|
||||
// * @returns {string} 连接ID
|
||||
// */
|
||||
// generateConnectionId() {
|
||||
// return 'conn_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 发送连接消息
|
||||
*/
|
||||
sendConnectMessage() {
|
||||
this.send('connect');
|
||||
}
|
||||
// /**
|
||||
// * 发送连接消息
|
||||
// */
|
||||
// sendConnectMessage() {
|
||||
// this.send('connect');
|
||||
// }
|
||||
|
||||
/**
|
||||
* 发送断开连接消息
|
||||
*/
|
||||
sendDisconnectMessage() {
|
||||
this.send('disconnect');
|
||||
}
|
||||
// /**
|
||||
// * 发送断开连接消息
|
||||
// */
|
||||
// sendDisconnectMessage() {
|
||||
// this.send('disconnect');
|
||||
// }
|
||||
|
||||
/**
|
||||
* 启动心跳
|
||||
*/
|
||||
startHeartbeat() {
|
||||
this.heartbeatInterval = setInterval(() => {
|
||||
if (this.isConnected) {
|
||||
this.send('ping');
|
||||
}
|
||||
}, 30000); // 每30秒发送一次心跳
|
||||
}
|
||||
// /**
|
||||
// * 启动心跳
|
||||
// */
|
||||
// startHeartbeat() {
|
||||
// this.heartbeatInterval = setInterval(() => {
|
||||
// if (this.isConnected) {
|
||||
// this.send('ping');
|
||||
// }
|
||||
// }, 30000); // 每30秒发送一次心跳
|
||||
// }
|
||||
|
||||
/**
|
||||
* 停止心跳
|
||||
*/
|
||||
stopHeartbeat() {
|
||||
if (this.heartbeatInterval) {
|
||||
clearInterval(this.heartbeatInterval);
|
||||
this.heartbeatInterval = null;
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 停止心跳
|
||||
// */
|
||||
// stopHeartbeat() {
|
||||
// if (this.heartbeatInterval) {
|
||||
// clearInterval(this.heartbeatInterval);
|
||||
// this.heartbeatInterval = null;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取连接ID
|
||||
* @returns {string} 连接ID
|
||||
*/
|
||||
getConnectionId() {
|
||||
return this.connectionId;
|
||||
}
|
||||
// /**
|
||||
// * 获取连接ID
|
||||
// * @returns {string} 连接ID
|
||||
// */
|
||||
// getConnectionId() {
|
||||
// return this.connectionId;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 订阅事件
|
||||
* @param {string} event - 事件名称
|
||||
* @param {Function} callback - 回调函数
|
||||
*/
|
||||
on(event, callback) {
|
||||
if (!this.listeners.has(event)) {
|
||||
this.listeners.set(event, []);
|
||||
}
|
||||
this.listeners.get(event).push(callback);
|
||||
}
|
||||
// /**
|
||||
// * 订阅事件
|
||||
// * @param {string} event - 事件名称
|
||||
// * @param {Function} callback - 回调函数
|
||||
// */
|
||||
// on(event, callback) {
|
||||
// if (!this.listeners.has(event)) {
|
||||
// this.listeners.set(event, []);
|
||||
// }
|
||||
// this.listeners.get(event).push(callback);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 取消订阅事件
|
||||
* @param {string} event - 事件名称
|
||||
* @param {Function} callback - 回调函数
|
||||
*/
|
||||
off(event, callback) {
|
||||
if (this.listeners.has(event)) {
|
||||
const callbacks = this.listeners.get(event);
|
||||
this.listeners.set(event, callbacks.filter(cb => cb !== callback));
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 取消订阅事件
|
||||
// * @param {string} event - 事件名称
|
||||
// * @param {Function} callback - 回调函数
|
||||
// */
|
||||
// off(event, callback) {
|
||||
// if (this.listeners.has(event)) {
|
||||
// const callbacks = this.listeners.get(event);
|
||||
// this.listeners.set(event, callbacks.filter(cb => cb !== callback));
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 触发事件
|
||||
* @param {string} event - 事件名称
|
||||
* @param {*} data - 事件数据
|
||||
*/
|
||||
emit(event, data) {
|
||||
if (this.listeners.has(event)) {
|
||||
this.listeners.get(event).forEach(callback => {
|
||||
try {
|
||||
callback(data);
|
||||
} catch (error) {
|
||||
console.error(`Error in event listener for ${event}:`, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 触发事件
|
||||
// * @param {string} event - 事件名称
|
||||
// * @param {*} data - 事件数据
|
||||
// */
|
||||
// emit(event, data) {
|
||||
// if (this.listeners.has(event)) {
|
||||
// this.listeners.get(event).forEach(callback => {
|
||||
// try {
|
||||
// callback(data);
|
||||
// } catch (error) {
|
||||
// console.error(`Error in event listener for ${event}:`, error);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 检查连接状态
|
||||
* @returns {boolean} 是否连接
|
||||
*/
|
||||
getIsConnected() {
|
||||
return this.isConnected;
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 检查连接状态
|
||||
// * @returns {boolean} 是否连接
|
||||
// */
|
||||
// getIsConnected() {
|
||||
// return this.isConnected;
|
||||
// }
|
||||
// }
|
||||
|
||||
// 创建单例实例
|
||||
const wsManager = new WebSocketManager();
|
||||
// // 创建单例实例
|
||||
// const wsManager = new WebSocketManager();
|
||||
|
||||
export default wsManager;
|
||||
// export default wsManager;
|
||||
|
||||
@@ -22,7 +22,7 @@ export class RenderStreaming {
|
||||
this.onGotAnswer = function (connectionId) { Logger.log(`On got Answer on ${connectionId}.`); };
|
||||
this.onTrackEvent = function (data) { Logger.log(`OnTrack event peer with data:${data}`); };
|
||||
this.onAddChannel = function (data) { Logger.log(`onAddChannel event peer with data:${data}`); };
|
||||
|
||||
this.onMessage = function (data) { Logger.log(`On message: ${data}`); };
|
||||
this._config = config;
|
||||
this._signaling = signaling;
|
||||
this._signaling.addEventListener('connect', this._onConnect.bind(this));
|
||||
@@ -30,6 +30,7 @@ export class RenderStreaming {
|
||||
this._signaling.addEventListener('offer', this._onOffer.bind(this));
|
||||
this._signaling.addEventListener('answer', this._onAnswer.bind(this));
|
||||
this._signaling.addEventListener('candidate', this._onIceCandidate.bind(this));
|
||||
this._signaling.addEventListener('on-message', this._onMessage.bind(this));
|
||||
}
|
||||
|
||||
async _onConnect(e) {
|
||||
@@ -85,7 +86,11 @@ export class RenderStreaming {
|
||||
await this._peer.onGotCandidate(candidate.connectionId, iceCandidate);
|
||||
}
|
||||
}
|
||||
|
||||
// 在 RenderStreaming 类中添加
|
||||
async _onMessage(e) {
|
||||
const data = e.detail;
|
||||
this.onMessage(data);
|
||||
}
|
||||
/**
|
||||
* if not set argument, a generated uuid is used.
|
||||
* @param {string | null} connectionId
|
||||
@@ -98,6 +103,7 @@ export class RenderStreaming {
|
||||
async deleteConnection() {
|
||||
await this._signaling.deleteConnection(this._connectionId);
|
||||
}
|
||||
// 在 RenderStreaming 类中添加
|
||||
|
||||
_preparePeerConnection(connectionId, polite) {
|
||||
if (this._peer) {
|
||||
@@ -182,6 +188,11 @@ export class RenderStreaming {
|
||||
return this._peer.getTransceivers(this._connectionId);
|
||||
}
|
||||
|
||||
sendMessage(message) {
|
||||
if (this._signaling && this._connectionId) {
|
||||
this._signaling.sendMessage(this._connectionId, message);
|
||||
}
|
||||
}
|
||||
async start() {
|
||||
await this._signaling.start();
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ export class Signaling extends EventTarget {
|
||||
}
|
||||
}
|
||||
|
||||
url(method, parameter='') {
|
||||
url(method, parameter = '') {
|
||||
let ret = location.origin + '/signaling';
|
||||
if(method)
|
||||
if (method)
|
||||
ret += '/' + method;
|
||||
if(parameter)
|
||||
if (parameter)
|
||||
ret += '?' + parameter;
|
||||
return ret;
|
||||
}
|
||||
|
||||
async start() {
|
||||
if(this.running) {
|
||||
if (this.running) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ export class Signaling extends EventTarget {
|
||||
|
||||
const messages = data.messages;
|
||||
|
||||
for(const msg of messages) {
|
||||
for (const msg of messages) {
|
||||
switch (msg.type) {
|
||||
case "connect":
|
||||
break;
|
||||
@@ -63,14 +63,17 @@ export class Signaling extends EventTarget {
|
||||
this.dispatchEvent(new CustomEvent('disconnect', { detail: msg }));
|
||||
break;
|
||||
case "offer":
|
||||
this.dispatchEvent(new CustomEvent('offer', { detail: msg } ));
|
||||
this.dispatchEvent(new CustomEvent('offer', { detail: msg }));
|
||||
break;
|
||||
case "answer":
|
||||
this.dispatchEvent(new CustomEvent('answer', { detail: msg } ));
|
||||
this.dispatchEvent(new CustomEvent('answer', { detail: msg }));
|
||||
break;
|
||||
case "candidate":
|
||||
this.dispatchEvent(new CustomEvent('candidate', { detail: msg }));
|
||||
break;
|
||||
case "on-message":
|
||||
this.dispatchEvent(new CustomEvent('on-message', { detail: msg.data }));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -125,7 +128,14 @@ export class Signaling extends EventTarget {
|
||||
Logger.log('sendCandidate:' + data);
|
||||
await fetch(this.url('candidate'), { method: 'POST', headers: this.headers(), body: JSON.stringify(data) });
|
||||
}
|
||||
|
||||
// 在 Signaling 类中添加
|
||||
async sendMessage(connectionId, message) {
|
||||
const data = {
|
||||
'message': message,
|
||||
'connectionId': connectionId
|
||||
};
|
||||
await fetch(this.url('on-message'), { method: 'POST', headers: this.headers(), body: JSON.stringify(data) });
|
||||
}
|
||||
async getAll(fromTime = 0) {
|
||||
return await fetch(this.url(``, `fromtime=${fromTime}`), { method: 'GET', headers: this.headers() });
|
||||
}
|
||||
@@ -180,6 +190,8 @@ export class WebSocketSignaling extends EventTarget {
|
||||
case "candidate":
|
||||
this.dispatchEvent(new CustomEvent('candidate', { detail: { connectionId: msg.from, candidate: msg.data.candidate, sdpMLineIndex: msg.data.sdpMLineIndex, sdpMid: msg.data.sdpMid } }));
|
||||
break;
|
||||
case "on-message":
|
||||
this.dispatchEvent(new CustomEvent('on-message', { detail: msg.data }));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -236,4 +248,15 @@ export class WebSocketSignaling extends EventTarget {
|
||||
Logger.log(sendJson);
|
||||
this.websocket.send(sendJson);
|
||||
}
|
||||
// 在 WebSocketSignaling 类中添加
|
||||
sendMessage(connectionId, message) {
|
||||
const data = {
|
||||
'message': message,
|
||||
'senderId': message.senderId,
|
||||
'connectionId': connectionId
|
||||
};
|
||||
const sendJson = JSON.stringify({ type: "on-message", data: data });
|
||||
Logger.log(sendJson);
|
||||
this.websocket.send(sendJson);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ function onCandidate(ws: WebSocket, message: any): void {
|
||||
* @param ws WebSocket连接实例
|
||||
* @param message 消息数据
|
||||
*/
|
||||
function onChatMessage(ws: WebSocket, message: any): void {
|
||||
function onMessage(ws: WebSocket, message: any): void {
|
||||
// 获取连接ID
|
||||
const connectionId = message.connectionId;
|
||||
const chatMessage = message.message;
|
||||
@@ -376,11 +376,11 @@ function onCandidate(ws: WebSocket, message: any): void {
|
||||
const otherSessionWs = pair[0] == ws ? pair[1] : pair[0];
|
||||
if (otherSessionWs) {
|
||||
// 发送chat-message消息
|
||||
otherSessionWs.send(JSON.stringify({ from: connectionId, to: "", type: "chat-message", data: chatMessage }));
|
||||
otherSessionWs.send(JSON.stringify({ from: connectionId, to: "", type: "on-message", data: chatMessage }));
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 导出WebSocket处理器函数
|
||||
*/
|
||||
export { reset, add, remove, onConnect, onDisconnect, onOffer, onAnswer, onCandidate, onCallConnectionId, onBroadcast, onGetAllConnectionIds, AddHeartbeat, RemoveHeartbeat ,onChatMessage};
|
||||
export { reset, add, remove, onConnect, onDisconnect, onOffer, onAnswer, onCandidate, onCallConnectionId, onBroadcast, onGetAllConnectionIds, AddHeartbeat, RemoveHeartbeat ,onMessage};
|
||||
|
||||
@@ -108,9 +108,9 @@ export default class WSSignaling {
|
||||
// 处理callConnectionId信令
|
||||
handler.onCallConnectionId(ws, msg.data);
|
||||
break;
|
||||
case 'chat-message'://接受连接ConnectionId
|
||||
case 'on-message'://接受连接ConnectionId
|
||||
// 处理chat-message信令
|
||||
handler.onChatMessage(ws, msg.data);
|
||||
handler.onMessage(ws, msg.data);
|
||||
break;
|
||||
default:
|
||||
// 忽略未知消息类型
|
||||
|
||||
Reference in New Issue
Block a user