【m】增加多用户连接
This commit is contained in:
@@ -8,15 +8,9 @@ import { RenderStreaming } from "../../module/renderstreaming.js"; // WebRTC连
|
||||
import { getServerConfig, getRTCConfiguration } from "../js/config.js";//服务器配置和RTC配置
|
||||
import { showNotification, generateId } from './utils.js'; // 导入通知函数
|
||||
import chatMessage from './chatmessage.js';
|
||||
// 默认视频流尺寸
|
||||
const defaultStreamWidth = 1280;
|
||||
const defaultStreamHeight = 720;
|
||||
|
||||
class CallStateManager {
|
||||
constructor() {
|
||||
const renderstreaming = null; // WebRTC连接管理实例
|
||||
const useWebSocket = null; // 是否使用WebSocket信令
|
||||
const connectionId = null; // 连接ID
|
||||
// 核心状态
|
||||
this.state = {
|
||||
id: generateId(),
|
||||
@@ -332,9 +326,23 @@ class CallStateManager {
|
||||
]
|
||||
};
|
||||
this.renderstreaming = new RenderStreaming(signaling, config); // 创建WebRTC连接管理实例
|
||||
|
||||
this.renderstreaming.onNewPeer = (connectionId) => {
|
||||
console.log(`New peer created for ${connectionId}, adding local tracks`);
|
||||
if (this.state.localStream) {
|
||||
const tracks = this.state.localStream.getTracks();
|
||||
for (const track of tracks) {
|
||||
this.renderstreaming.addTransceiver(track, { direction: 'sendonly' });
|
||||
}
|
||||
this.setCodecPreferences();
|
||||
}
|
||||
};
|
||||
// 连接建立回调
|
||||
this.renderstreaming.onConnect = () => {
|
||||
this.renderstreaming.onConnect = (connectionId, data) => {
|
||||
// 保存角色信息(host/participant)
|
||||
if (data && data.role) {
|
||||
this.role = data.role;
|
||||
console.log(`Connected as ${this.role}`);
|
||||
}
|
||||
// 连接建立后,更新状态为ongoing
|
||||
this.state.session.status = 'ongoing';
|
||||
this.notify({ type: 'CALL_STATUS_CHANGE', status: 'ongoing' });
|
||||
@@ -347,21 +355,39 @@ class CallStateManager {
|
||||
});
|
||||
|
||||
if (this.state.localStream) {
|
||||
const tracks = this.state.localStream.getTracks(); // 获取本地媒体轨道
|
||||
for (const track of tracks) {
|
||||
this.renderstreaming.addTransceiver(track, { direction: 'sendonly' }); // 添加发送轨道
|
||||
}
|
||||
this.setCodecPreferences(); // 设置编解码器偏好
|
||||
this.showStatsMessage(); // 显示统计信息
|
||||
// const tracks = this.state.localStream.getTracks();
|
||||
// for (const track of tracks) {
|
||||
// this.renderstreaming.addTransceiver(track, { direction: 'sendonly' });
|
||||
// }
|
||||
// this.setCodecPreferences();
|
||||
this.showStatsMessage();
|
||||
} else {
|
||||
console.error('Local stream is not available');
|
||||
showNotification('本地视频流不可用', 'error');
|
||||
}
|
||||
};
|
||||
|
||||
// 连接断开回调
|
||||
// 连接断开回调(收到服务器的 disconnect 消息,通常是 host 离开导致房间关闭)
|
||||
this.renderstreaming.onDisconnect = () => {
|
||||
this.hangUp(); // 挂断连接
|
||||
console.log('Received disconnect from server, host left or room closed');
|
||||
this.hangUp(); // 房间已关闭,挂断连接
|
||||
};
|
||||
|
||||
// participant离开回调(host收到,房间仍然存在)
|
||||
this.renderstreaming.onParticipantLeft = (connectionId) => {
|
||||
console.log(`Participant left: ${connectionId}, room still active`);
|
||||
// 更新远程用户状态,但不关闭房间
|
||||
this.updateRemoteUserStatus('offline');
|
||||
this.updateRemoteUserNetworkQuality('no_signal');
|
||||
showNotification('对方已离开通话', 'warning');
|
||||
// 清理远端流,重置Peer连接为新participant加入做准备
|
||||
if (this.state.remoteStream) {
|
||||
this.state.remoteStream.getTracks().forEach(track => track.stop());
|
||||
this.state.remoteStream = null;
|
||||
}
|
||||
this.notify({ type: 'REMOTE_STREAM_OBTAINED', stream: null });
|
||||
// 通知UI更新
|
||||
this.notify({ type: 'PARTICIPANT_LEFT', connectionId: connectionId });
|
||||
};
|
||||
|
||||
// 轨道事件回调
|
||||
@@ -473,6 +499,8 @@ class CallStateManager {
|
||||
|
||||
/**
|
||||
* 挂断WebRTC连接
|
||||
* Host挂断:房间删除,通知所有participants
|
||||
* Participant挂断:仅自己离开,房间保留
|
||||
* @async
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
@@ -484,11 +512,17 @@ class CallStateManager {
|
||||
clearInterval(this.durationInterval);
|
||||
this.durationInterval = null;
|
||||
}
|
||||
console.log(`Disconnect peer on ${this.connectionId}.`);
|
||||
|
||||
const isHost = this.role === 'host';
|
||||
console.log(`Disconnect peer on ${this.connectionId}. Role: ${this.role}`);
|
||||
|
||||
// 删除连接并停止WebRTC
|
||||
if (this.renderstreaming) {
|
||||
try {
|
||||
// 发送断开连接信令给服务器
|
||||
// 服务器会根据角色决定:
|
||||
// - host断开:通知所有participants,删除房间
|
||||
// - participant断开:仅通知host,保留房间
|
||||
await this.renderstreaming.deleteConnection();
|
||||
await this.renderstreaming.stop();
|
||||
} catch (error) {
|
||||
@@ -501,8 +535,9 @@ class CallStateManager {
|
||||
this.updateRemoteUserStatus('offline');
|
||||
this.updateRemoteUserNetworkQuality('no_signal');
|
||||
this.connectionId = null;
|
||||
this.role = null;
|
||||
this.state.session.status = 'ended';
|
||||
this.notify({ type: 'CALL_ENDED' });
|
||||
this.notify({ type: 'CALL_ENDED', reason: isHost ? 'host_hangup' : 'participant_hangup' });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -570,18 +605,14 @@ class CallStateManager {
|
||||
this.state.session.remoteUser.networkQuality = networkQuality;
|
||||
this.notify({ type: 'REMOTE_MEDIA_CHANGE', localUser: this.state.session.localUser, remoteUser: this.state.session.remoteUser });
|
||||
}
|
||||
// 结束通话
|
||||
endCall() {
|
||||
if (this.durationInterval) {
|
||||
clearInterval(this.durationInterval);
|
||||
this.durationInterval = null;
|
||||
}
|
||||
this.state.session.status = 'ended';
|
||||
this.notify({ type: 'CALL_ENDED' });
|
||||
|
||||
// 发送结束通话请求到服务器
|
||||
// [API_CALL: POST /api/call/:callId/leave]
|
||||
// [WEBSOCKET_EMIT: leave-call]
|
||||
// 结束通话(用户主动点击挂断按钮)
|
||||
async endCall() {
|
||||
console.log(`endCall called. Role: ${this.role}`);
|
||||
// 调用 hangUp() 正确关闭 WebRTC 连接并发送断开信令
|
||||
// hangUp 内部会根据角色区分:
|
||||
// - host: 通知所有participants,删除房间
|
||||
// - participant: 仅自己离开,房间保留
|
||||
await this.hangUp();
|
||||
}
|
||||
|
||||
// 加入通话
|
||||
|
||||
Reference in New Issue
Block a user