【m】聊天消息接入

This commit is contained in:
zhangzheng
2026-03-12 12:10:40 +08:00
parent b4c41e42c9
commit e9f7b3ad5c
7 changed files with 425 additions and 359 deletions

View File

@@ -5,7 +5,7 @@
import store from './store.js'; import store from './store.js';
import UIRenderer from './renderer.js'; import UIRenderer from './renderer.js';
import apiClient from './api.js'; import apiClient from './api.js';
import wsManager from './websocket.js'; // import wsManager from './websocket.js';
import { mockCallSession } from './models.js'; import { mockCallSession } from './models.js';
import { showNotification, generateId } from './utils.js'; import { showNotification, generateId } from './utils.js';
@@ -39,75 +39,75 @@ let connectionId = "";
* 绑定WebSocket事件 * 绑定WebSocket事件
*/ */
function bindWebSocketEvents() { function bindWebSocketEvents() {
wsManager.on('connect', () => { // wsManager.on('connect', () => {
console.log('WebSocket connected'); // console.log('WebSocket connected');
showNotification('已连接到服务器'); // showNotification('已连接到服务器');
}); // });
wsManager.on('disconnect', () => { // wsManager.on('disconnect', () => {
console.log('WebSocket disconnected'); // console.log('WebSocket disconnected');
showNotification('与服务器的连接已断开', 5000); // showNotification('与服务器的连接已断开', 5000);
}); // });
wsManager.on('message-received', (data) => { // wsManager.on('message-received', (data) => {
console.log('Message received:', data); // console.log('Message received:', data);
store.addMessage(data.message); // store.addMessage(data.message);
}); // });
wsManager.on('user-joined', (data) => { // wsManager.on('user-joined', (data) => {
console.log('User joined:', data); // console.log('User joined:', data);
showNotification(`${data.userId} 加入了通话`); // showNotification(`${data.userId} 加入了通话`);
}); // });
wsManager.on('user-left', (data) => { // wsManager.on('user-left', (data) => {
console.log('User left:', data); // console.log('User left:', data);
showNotification(`${data.userId} 离开了通话`); // showNotification(`${data.userId} 离开了通话`);
}); // });
wsManager.on('media-state-changed', (data) => { // wsManager.on('media-state-changed', (data) => {
console.log('Media state changed:', data); // console.log('Media state changed:', data);
// 更新远端媒体状态 // // 更新远端媒体状态
if (data.userId !== store.getLocalUser().id) { // if (data.userId !== store.getLocalUser().id) {
store.updateRemoteMedia(data); // store.updateRemoteMedia(data);
} // }
}); // });
wsManager.on('network-quality', (data) => { // wsManager.on('network-quality', (data) => {
console.log('Network quality changed:', data); // console.log('Network quality changed:', data);
// 更新网络质量 // // 更新网络质量
const state = store.getState(); // const state = store.getState();
if (data.userId === state.session.remoteUser.id) { // if (data.userId === state.session.remoteUser.id) {
state.session.remoteUser.networkQuality = data.quality; // state.session.remoteUser.networkQuality = data.quality;
store.notify({ type: 'NETWORK_CHANGE', quality: data.quality }); // store.notify({ type: 'NETWORK_CHANGE', quality: data.quality });
} // }
}); // });
wsManager.on('call-ended', (data) => { // wsManager.on('call-ended', (data) => {
console.log('Call ended:', data); // console.log('Call ended:', data);
store.endCall(); // store.endCall();
showNotification('通话已结束', 3000); // showNotification('通话已结束', 3000);
}); // });
wsManager.on('call-request', (data) => { // wsManager.on('call-request', (data) => {
console.log('Call request received:', data); // console.log('Call request received:', data);
// 显示通话请求弹窗 // // 显示通话请求弹窗
if (window.showCallRequest) { // if (window.showCallRequest) {
const caller = { // const caller = {
name: mockCallSession.remoteUser.name, // name: mockCallSession.remoteUser.name,
avatar: mockCallSession.remoteUser.avatar // avatar: mockCallSession.remoteUser.avatar
}; // };
window.showCallRequest(caller); // window.showCallRequest(caller);
connectionId = data.connectionId; // connectionId = data.connectionId;
} // }
}); // });
//处理发送消息响应 // //处理发送消息响应
wsManager.on('chat-message', (data) => { // wsManager.on('chat-message', (data) => {
console.log('chat-message:', data); // console.log('chat-message:', data);
// 显示消息 // // 显示消息
store.addMessage({ // store.addMessage({
data: data.message, // data: data.message,
}); // });
}); // });
} }
/** /**
@@ -216,8 +216,8 @@ function bindDomEvents() {
if (content) { if (content) {
const state = store.getState(); const state = store.getState();
const newMessage = { const message = {
id: generateId(), id: state.id,
senderId: state.session.localUser.id, senderId: state.session.localUser.id,
senderName: state.session.localUser.name, senderName: state.session.localUser.name,
senderAvatar: state.session.localUser.avatar, senderAvatar: state.session.localUser.avatar,
@@ -227,14 +227,25 @@ function bindDomEvents() {
isSelf: true isSelf: true
}; };
store.addMessage(newMessage); store.addMessage(message);
chatInput.value = '';
const message = {
connectionId: connectionId, const newMessage = {
message: 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 };

View File

@@ -6,13 +6,14 @@ import { mockCallSession, mockMessages } from './models.js';
import { Signaling, WebSocketSignaling } from "../../module/signaling.js";// 信令管理 import { Signaling, WebSocketSignaling } from "../../module/signaling.js";// 信令管理
import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理 import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理
import { getServerConfig, getRTCConfiguration } from "../js/config.js";//服务器配置和RTC配置 import { getServerConfig, getRTCConfiguration } from "../js/config.js";//服务器配置和RTC配置
import { showNotification } from './utils.js'; // 导入通知函数 import { showNotification, generateId } from './utils.js'; // 导入通知函数
// 默认视频流尺寸 // 默认视频流尺寸
const defaultStreamWidth = 1280; const defaultStreamWidth = 1280;
const defaultStreamHeight = 720; const defaultStreamHeight = 720;
class CallStateManager { class CallStateManager {
constructor() { constructor() {
const renderstreaming = null; // WebRTC连接管理实例 const renderstreaming = null; // WebRTC连接管理实例
@@ -20,6 +21,7 @@ class CallStateManager {
const connectionId = null; // 连接ID const connectionId = null; // 连接ID
// 核心状态 // 核心状态
this.state = { this.state = {
id: generateId(),
session: { session: {
...mockCallSession, ...mockCallSession,
status: 'idle' // 初始状态为空闲 status: 'idle' // 初始状态为空闲
@@ -255,6 +257,7 @@ class CallStateManager {
} }
/** /**
* 设置WebRTC连接 * 设置WebRTC连接
* @async * @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连接 // 启动WebRTC连接
await this.renderstreaming.start(); await this.renderstreaming.start();
await this.renderstreaming.createConnection(connectionId); await this.renderstreaming.createConnection(connectionId);
@@ -454,7 +467,15 @@ class CallStateManager {
this.notify({ type: 'NEW_MESSAGE', message, unreadCount: this.state.unreadCount }); this.notify({ type: 'NEW_MESSAGE', message, unreadCount: this.state.unreadCount });
} }
sendChatMessage(message) {
if (this.renderstreaming) {
this.renderstreaming.sendMessage({
type: 'chat-message',
message: message,
});
}
}
// 切换侧边栏 // 切换侧边栏
toggleSidebar() { toggleSidebar() {
this.state.isSidebarOpen = !this.state.isSidebarOpen; this.state.isSidebarOpen = !this.state.isSidebarOpen;
@@ -595,7 +616,7 @@ class CallStateManager {
console.error('Error detecting network quality:', error); console.error('Error detecting network quality:', error);
} }
} }
// 真实音频活动检测 - 远端 // 真实音频活动检测 - 远端
startRemoteActivityDetection() { startRemoteActivityDetection() {
// 检查是否有远端音频流 // 检查是否有远端音频流
if (!this.state.remoteStream) { if (!this.state.remoteStream) {

View File

@@ -1,303 +1,303 @@
/** // /**
* WebSocket管理 // * WebSocket管理
* 管理WebSocket连接处理WebSocket事件 // * 管理WebSocket连接处理WebSocket事件
*/ // */
import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理 // import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连接管理
class WebSocketManager { // class WebSocketManager {
constructor() { // constructor() {
this.isConnected = false; // this.isConnected = false;
} // }
/** // /**
* 获取默认WebSocket URL // * 获取默认WebSocket URL
* @returns {string} WebSocket URL // * @returns {string} WebSocket URL
*/ // */
getDefaultWebSocketUrl() { // getDefaultWebSocketUrl() {
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:'; // const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
return `${protocol}//${location.host}`; // return `${protocol}//${location.host}`;
} // }
/** // /**
* 连接WebSocket // * 连接WebSocket
*/ // */
init() { // init() {
try { // try {
RenderStreaming.onConnect = () => { // RenderStreaming.onConnect = () => {
console.log('WebSocket connected'); // console.log('WebSocket connected');
this.isConnected = true; // this.isConnected = true;
// // 发送连接消息 // // // 发送连接消息
// this.sendConnectMessage(); // // this.sendConnectMessage();
// // 启动心跳 // // // 启动心跳
this.startHeartbeat(); // this.startHeartbeat();
// this.emit('connect'); // // this.emit('connect');
}; // };
RenderStreaming.onDisconnect = () => { // RenderStreaming.onDisconnect = () => {
console.log('WebSocket disconnected'); // console.log('WebSocket disconnected');
this.isConnected = false; // this.isConnected = false;
this.stopHeartbeat(); // this.stopHeartbeat();
//this.emit('disconnect'); // //this.emit('disconnect');
//this.attemptReconnect(); // //this.attemptReconnect();
}; // };
RenderStreaming.onmessage = (event) => { // RenderStreaming.onmessage = (event) => {
try { // try {
const message = JSON.parse(event.data); // const message = JSON.parse(event.data);
this.handleMessage(message); // this.handleMessage(message);
} catch (error) { // } catch (error) {
console.error('Error parsing WebSocket message:', error); // console.error('Error parsing WebSocket message:', error);
} // }
}; // };
this.socket.onerror = (error) => { // this.socket.onerror = (error) => {
console.error('WebSocket error:', error); // console.error('WebSocket error:', error);
this.emit('error', error); // this.emit('error', error);
}; // };
} catch (error) { // } catch (error) {
console.error('Error connecting to WebSocket:', error); // console.error('Error connecting to WebSocket:', error);
this.emit('error', error); // this.emit('error', error);
} // }
} // }
/** // /**
* 断开WebSocket连接 // * 断开WebSocket连接
*/ // */
disconnect() { // disconnect() {
if (this.socket) { // if (this.socket) {
this.socket.close(); // this.socket.close();
this.socket = null; // this.socket = null;
this.isConnected = false; // this.isConnected = false;
} // }
} // }
/** // /**
* 发送消息 // * 发送消息
* @param {string} type - 消息类型 // * @param {string} type - 消息类型
* @param {Object} data - 消息数据 // * @param {Object} data - 消息数据
*/ // */
send(type, data) { // send(type, data) {
if (this.isConnected && this.socket) { // if (this.isConnected && this.socket) {
try { // try {
let message; // let message;
// 根据消息类型构建不同的消息格式 // // 根据消息类型构建不同的消息格式
if (type === 'connect' || type === 'disconnect') { // if (type === 'connect' || type === 'disconnect') {
message = JSON.stringify({ type, connectionId: this.connectionId }); // message = JSON.stringify({ type, connectionId: this.connectionId });
} else if (type === 'offer' || type === 'answer' || type === 'candidate') { // } else if (type === 'offer' || type === 'answer' || type === 'candidate') {
message = JSON.stringify({ type, data }); // message = JSON.stringify({ type, data });
} else if (type === 'broadcast') { // } else if (type === 'broadcast') {
message = JSON.stringify({ type, message: data.message, targetConnectionId: data.targetConnectionId }); // message = JSON.stringify({ type, message: data.message, targetConnectionId: data.targetConnectionId });
} else if (type === 'ping' || type === 'pong') { // } else if (type === 'ping' || type === 'pong') {
message = JSON.stringify({ type }); // message = JSON.stringify({ type });
} else { // } else {
// 兼容旧格式,用于自定义事件 // // 兼容旧格式,用于自定义事件
message = JSON.stringify({ event: type, data }); // message = JSON.stringify({ event: type, data });
} // }
this.socket.send(message); // this.socket.send(message);
} catch (error) { // } catch (error) {
console.error('Error sending WebSocket message:', error); // console.error('Error sending WebSocket message:', error);
} // }
} else { // } else {
console.warn('WebSocket not connected, cannot send message'); // console.warn('WebSocket not connected, cannot send message');
} // }
} // }
/** // /**
* 处理接收到的消息 // * 处理接收到的消息
* @param {Object} message - 消息对象 // * @param {Object} message - 消息对象
*/ // */
handleMessage(message) { // handleMessage(message) {
if (message.type) { // if (message.type) {
console.log('Received message:', message); // console.log('Received message:', message);
switch (message.type) { // switch (message.type) {
case 'user-joined': // case 'user-joined':
this.emit('user-joined', message.data); // this.emit('user-joined', message.data);
break; // break;
case 'user-left': // case 'user-left':
this.emit('user-left', message.data); // this.emit('user-left', message.data);
break; // break;
case 'media-state-changed': // case 'media-state-changed':
this.emit('media-state-changed', message.data); // this.emit('media-state-changed', message.data);
break; // break;
case 'message-received': // case 'message-received':
this.emit('message-received', message.data); // this.emit('message-received', message.data);
break; // break;
case 'network-quality': // case 'network-quality':
this.emit('network-quality', message.data); // this.emit('network-quality', message.data);
break; // break;
case 'call-ended': // case 'call-ended':
this.emit('call-ended', message.data); // this.emit('call-ended', message.data);
break; // break;
case 'call-request': // case 'call-request':
this.emit('call-request', message.data); // this.emit('call-request', message.data);
break; // break;
case 'ping': // case 'ping':
// 处理心跳请求回复pong // // 处理心跳请求回复pong
this.send('pong'); // this.send('pong');
break; // break;
case 'pong': // case 'pong':
// 处理心跳响应 // // 处理心跳响应
this.emit('pong'); // this.emit('pong');
break; // break;
case 'offer': // case 'offer':
this.emit('offer', message.data); // this.emit('offer', message.data);
break; // break;
case 'answer': // case 'answer':
this.emit('answer', message.data); // this.emit('answer', message.data);
break; // break;
case 'candidate': // case 'candidate':
this.emit('candidate', message.data); // this.emit('candidate', message.data);
break; // break;
case 'chat-message': // case 'chat-message':
this.emit('chat-message', message.data); // this.emit('chat-message', message.data);
break; // break;
default: // default:
// 处理旧格式消息 // // 处理旧格式消息
if (message.event) { // if (message.event) {
this.emit(message.event, message.data); // this.emit(message.event, message.data);
} else { // } else {
this.emit('message', message); // this.emit('message', message);
} // }
break; // break;
} // }
} else if (message.event) { // } else if (message.event) {
// 处理旧格式消息 // // 处理旧格式消息
this.emit(message.event, message.data); // this.emit(message.event, message.data);
} else { // } else {
this.emit('message', message); // this.emit('message', message);
} // }
} // }
/** // /**
* 尝试重连 // * 尝试重连
*/ // */
attemptReconnect() { // attemptReconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) { // if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++; // this.reconnectAttempts++;
const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1); // 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(() => { // setTimeout(() => {
console.log(`Reconnect attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}`); // console.log(`Reconnect attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
this.connect(); // this.connect();
}, delay); // }, delay);
} else { // } else {
console.error('Max reconnect attempts reached'); // console.error('Max reconnect attempts reached');
this.emit('reconnect-failed'); // this.emit('reconnect-failed');
} // }
} // }
/** // /**
* 生成连接ID // * 生成连接ID
* @returns {string} 连接ID // * @returns {string} 连接ID
*/ // */
generateConnectionId() { // generateConnectionId() {
return 'conn_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); // return 'conn_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
} // }
/** // /**
* 发送连接消息 // * 发送连接消息
*/ // */
sendConnectMessage() { // sendConnectMessage() {
this.send('connect'); // this.send('connect');
} // }
/** // /**
* 发送断开连接消息 // * 发送断开连接消息
*/ // */
sendDisconnectMessage() { // sendDisconnectMessage() {
this.send('disconnect'); // this.send('disconnect');
} // }
/** // /**
* 启动心跳 // * 启动心跳
*/ // */
startHeartbeat() { // startHeartbeat() {
this.heartbeatInterval = setInterval(() => { // this.heartbeatInterval = setInterval(() => {
if (this.isConnected) { // if (this.isConnected) {
this.send('ping'); // this.send('ping');
} // }
}, 30000); // 每30秒发送一次心跳 // }, 30000); // 每30秒发送一次心跳
} // }
/** // /**
* 停止心跳 // * 停止心跳
*/ // */
stopHeartbeat() { // stopHeartbeat() {
if (this.heartbeatInterval) { // if (this.heartbeatInterval) {
clearInterval(this.heartbeatInterval); // clearInterval(this.heartbeatInterval);
this.heartbeatInterval = null; // this.heartbeatInterval = null;
} // }
} // }
/** // /**
* 获取连接ID // * 获取连接ID
* @returns {string} 连接ID // * @returns {string} 连接ID
*/ // */
getConnectionId() { // getConnectionId() {
return this.connectionId; // return this.connectionId;
} // }
/** // /**
* 订阅事件 // * 订阅事件
* @param {string} event - 事件名称 // * @param {string} event - 事件名称
* @param {Function} callback - 回调函数 // * @param {Function} callback - 回调函数
*/ // */
on(event, callback) { // on(event, callback) {
if (!this.listeners.has(event)) { // if (!this.listeners.has(event)) {
this.listeners.set(event, []); // this.listeners.set(event, []);
} // }
this.listeners.get(event).push(callback); // this.listeners.get(event).push(callback);
} // }
/** // /**
* 取消订阅事件 // * 取消订阅事件
* @param {string} event - 事件名称 // * @param {string} event - 事件名称
* @param {Function} callback - 回调函数 // * @param {Function} callback - 回调函数
*/ // */
off(event, callback) { // off(event, callback) {
if (this.listeners.has(event)) { // if (this.listeners.has(event)) {
const callbacks = this.listeners.get(event); // const callbacks = this.listeners.get(event);
this.listeners.set(event, callbacks.filter(cb => cb !== callback)); // this.listeners.set(event, callbacks.filter(cb => cb !== callback));
} // }
} // }
/** // /**
* 触发事件 // * 触发事件
* @param {string} event - 事件名称 // * @param {string} event - 事件名称
* @param {*} data - 事件数据 // * @param {*} data - 事件数据
*/ // */
emit(event, data) { // emit(event, data) {
if (this.listeners.has(event)) { // if (this.listeners.has(event)) {
this.listeners.get(event).forEach(callback => { // this.listeners.get(event).forEach(callback => {
try { // try {
callback(data); // callback(data);
} catch (error) { // } catch (error) {
console.error(`Error in event listener for ${event}:`, error); // console.error(`Error in event listener for ${event}:`, error);
} // }
}); // });
} // }
} // }
/** // /**
* 检查连接状态 // * 检查连接状态
* @returns {boolean} 是否连接 // * @returns {boolean} 是否连接
*/ // */
getIsConnected() { // getIsConnected() {
return this.isConnected; // return this.isConnected;
} // }
} // }
// 创建单例实例 // // 创建单例实例
const wsManager = new WebSocketManager(); // const wsManager = new WebSocketManager();
export default wsManager; // export default wsManager;

View File

@@ -22,7 +22,7 @@ export class RenderStreaming {
this.onGotAnswer = function (connectionId) { Logger.log(`On got Answer on ${connectionId}.`); }; this.onGotAnswer = function (connectionId) { Logger.log(`On got Answer on ${connectionId}.`); };
this.onTrackEvent = function (data) { Logger.log(`OnTrack event peer with data:${data}`); }; 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.onAddChannel = function (data) { Logger.log(`onAddChannel event peer with data:${data}`); };
this.onMessage = function (data) { Logger.log(`On message: ${data}`); };
this._config = config; this._config = config;
this._signaling = signaling; this._signaling = signaling;
this._signaling.addEventListener('connect', this._onConnect.bind(this)); 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('offer', this._onOffer.bind(this));
this._signaling.addEventListener('answer', this._onAnswer.bind(this)); this._signaling.addEventListener('answer', this._onAnswer.bind(this));
this._signaling.addEventListener('candidate', this._onIceCandidate.bind(this)); this._signaling.addEventListener('candidate', this._onIceCandidate.bind(this));
this._signaling.addEventListener('on-message', this._onMessage.bind(this));
} }
async _onConnect(e) { async _onConnect(e) {
@@ -85,7 +86,11 @@ export class RenderStreaming {
await this._peer.onGotCandidate(candidate.connectionId, iceCandidate); 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. * if not set argument, a generated uuid is used.
* @param {string | null} connectionId * @param {string | null} connectionId
@@ -98,6 +103,7 @@ export class RenderStreaming {
async deleteConnection() { async deleteConnection() {
await this._signaling.deleteConnection(this._connectionId); await this._signaling.deleteConnection(this._connectionId);
} }
// 在 RenderStreaming 类中添加
_preparePeerConnection(connectionId, polite) { _preparePeerConnection(connectionId, polite) {
if (this._peer) { if (this._peer) {
@@ -182,6 +188,11 @@ export class RenderStreaming {
return this._peer.getTransceivers(this._connectionId); return this._peer.getTransceivers(this._connectionId);
} }
sendMessage(message) {
if (this._signaling && this._connectionId) {
this._signaling.sendMessage(this._connectionId, message);
}
}
async start() { async start() {
await this._signaling.start(); await this._signaling.start();
} }

View File

@@ -18,17 +18,17 @@ export class Signaling extends EventTarget {
} }
} }
url(method, parameter='') { url(method, parameter = '') {
let ret = location.origin + '/signaling'; let ret = location.origin + '/signaling';
if(method) if (method)
ret += '/' + method; ret += '/' + method;
if(parameter) if (parameter)
ret += '?' + parameter; ret += '?' + parameter;
return ret; return ret;
} }
async start() { async start() {
if(this.running) { if (this.running) {
return; return;
} }
@@ -55,7 +55,7 @@ export class Signaling extends EventTarget {
const messages = data.messages; const messages = data.messages;
for(const msg of messages) { for (const msg of messages) {
switch (msg.type) { switch (msg.type) {
case "connect": case "connect":
break; break;
@@ -63,14 +63,17 @@ export class Signaling extends EventTarget {
this.dispatchEvent(new CustomEvent('disconnect', { detail: msg })); this.dispatchEvent(new CustomEvent('disconnect', { detail: msg }));
break; break;
case "offer": case "offer":
this.dispatchEvent(new CustomEvent('offer', { detail: msg } )); this.dispatchEvent(new CustomEvent('offer', { detail: msg }));
break; break;
case "answer": case "answer":
this.dispatchEvent(new CustomEvent('answer', { detail: msg } )); this.dispatchEvent(new CustomEvent('answer', { detail: msg }));
break; break;
case "candidate": case "candidate":
this.dispatchEvent(new CustomEvent('candidate', { detail: msg })); this.dispatchEvent(new CustomEvent('candidate', { detail: msg }));
break; break;
case "on-message":
this.dispatchEvent(new CustomEvent('on-message', { detail: msg.data }));
break;
default: default:
break; break;
} }
@@ -125,7 +128,14 @@ export class Signaling extends EventTarget {
Logger.log('sendCandidate:' + data); Logger.log('sendCandidate:' + data);
await fetch(this.url('candidate'), { method: 'POST', headers: this.headers(), body: JSON.stringify(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) { async getAll(fromTime = 0) {
return await fetch(this.url(``, `fromtime=${fromTime}`), { method: 'GET', headers: this.headers() }); return await fetch(this.url(``, `fromtime=${fromTime}`), { method: 'GET', headers: this.headers() });
} }
@@ -180,6 +190,8 @@ export class WebSocketSignaling extends EventTarget {
case "candidate": case "candidate":
this.dispatchEvent(new CustomEvent('candidate', { detail: { connectionId: msg.from, candidate: msg.data.candidate, sdpMLineIndex: msg.data.sdpMLineIndex, sdpMid: msg.data.sdpMid } })); this.dispatchEvent(new CustomEvent('candidate', { detail: { connectionId: msg.from, candidate: msg.data.candidate, sdpMLineIndex: msg.data.sdpMLineIndex, sdpMid: msg.data.sdpMid } }));
break; break;
case "on-message":
this.dispatchEvent(new CustomEvent('on-message', { detail: msg.data }));
default: default:
break; break;
} }
@@ -236,4 +248,15 @@ export class WebSocketSignaling extends EventTarget {
Logger.log(sendJson); Logger.log(sendJson);
this.websocket.send(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);
}
} }

View File

@@ -366,7 +366,7 @@ function onCandidate(ws: WebSocket, message: any): void {
* @param ws WebSocket连接实例 * @param ws WebSocket连接实例
* @param message 消息数据 * @param message 消息数据
*/ */
function onChatMessage(ws: WebSocket, message: any): void { function onMessage(ws: WebSocket, message: any): void {
// 获取连接ID // 获取连接ID
const connectionId = message.connectionId; const connectionId = message.connectionId;
const chatMessage = message.message; const chatMessage = message.message;
@@ -376,11 +376,11 @@ function onCandidate(ws: WebSocket, message: any): void {
const otherSessionWs = pair[0] == ws ? pair[1] : pair[0]; const otherSessionWs = pair[0] == ws ? pair[1] : pair[0];
if (otherSessionWs) { if (otherSessionWs) {
// 发送chat-message消息 // 发送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处理器函数 * 导出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};

View File

@@ -108,9 +108,9 @@ export default class WSSignaling {
// 处理callConnectionId信令 // 处理callConnectionId信令
handler.onCallConnectionId(ws, msg.data); handler.onCallConnectionId(ws, msg.data);
break; break;
case 'chat-message'://接受连接ConnectionId case 'on-message'://接受连接ConnectionId
// 处理chat-message信令 // 处理chat-message信令
handler.onChatMessage(ws, msg.data); handler.onMessage(ws, msg.data);
break; break;
default: default:
// 忽略未知消息类型 // 忽略未知消息类型