Files
PrivyDrop/frontend/lib/webrtc_Initiator.ts
T
2025-05-23 22:41:56 +08:00

100 lines
4.0 KiB
TypeScript

// 发起方 流程: 加入房间; 收到 'ready' 事件(新的接收方进入后socker server就会触发这个事件) -> createPeerConnection + createDataChannel -> createAndSendOffer
import BaseWebRTC from './webrtc_base';
import { postLogInDebug } from '@/app/config/api';
const developmentEnv = process.env.NEXT_PUBLIC_development!;//开发环境
export default class WebRTC_Initiator extends BaseWebRTC {
constructor(signalingServer: string) {
super(signalingServer);
this.setupInitiatorSocketListeners();
}
private setupInitiatorSocketListeners() {
this.socket.on('ready', ({ peerId }) => {//新进入房间的 接收方 peerId
this.handleReady({ peerId });
});
// 添加接收方响应的监听
this.socket.on('recipient-ready', ({ peerId }) => {
if (developmentEnv === 'true')postLogInDebug(`[Initiator] Received recipient-ready from: ${peerId}`);
this.handleReady({ peerId });
});
// 添加answer处理监听器
this.socket.on('answer', ({ answer, peerId, from }) => {
this.handleAnswer({ answer, peerId, from });
});
}
//发送方收到接收方加入时创建连接
private async handleReady({ peerId }: { peerId: string }): Promise<void> {//接收方 peerId
// console.log(`Received ready signal from peer ${peerId}`);
if (developmentEnv === 'true')postLogInDebug(`Received ready signal from peer ${peerId}`);
await this.createPeerConnection(peerId);
await this.createDataChannel(peerId);
await this.createAndSendOffer(peerId);
}
private async handleAnswer({ answer, peerId, from }: { answer: RTCSessionDescriptionInit; peerId: string; from: string }): Promise<void> {
// console.log(`Handling answer from peer ${from}`);
if (developmentEnv === 'true')postLogInDebug(`Handling answer from peer ${from}`);
const peerConnection = this.peerConnections.get(from);
if (!peerConnection) {
console.error(`No peer connection found for peer ${from}`);
return;
}
try {
await peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
// console.log(`Remote description set for peer ${from}`);
// 在设置远程描述后处理队列中的ICE候选
await this.addQueuedIceCandidates(from);
} catch (error) {
console.error('Error handling answer:', error);
}
}
protected async createDataChannel(peerId: string): Promise<void> {
const peerConnection = this.peerConnections.get(peerId);
if (!peerConnection) {
console.error(`No peer connection found for peer ${peerId}`);
return;
}
try {
const dataChannel = peerConnection.createDataChannel('dataChannel', {
ordered: true,
// reliable: true
});
// console.log(`Created data channel for peer ${peerId}`);
dataChannel.bufferedAmountLowThreshold = 262144; //256 KB -- 可以根据需要调整
this.setupDataChannel(dataChannel, peerId);
this.dataChannels.set(peerId, dataChannel);
} catch (error) {
console.error(`Error creating data channel for peer ${peerId}:`, error);
}
}
// 如果是发起方,创建并发送offer给信令服务器,以便与接收方协商建立连接。
private async createAndSendOffer(peerId: string): Promise<void> {
// console.log('createAndSendOffer',peerId);
if (developmentEnv === 'true')postLogInDebug(`createAndSendOffer for peerId: ${peerId}`);
const peerConnection = this.peerConnections.get(peerId);
if (!peerConnection) {
console.error(`No peer connection found for peer ${peerId}`);
return;
}
try {
const offer = await peerConnection.createOffer();
await peerConnection.setLocalDescription(offer);
// console.log('createAndSendOffer',peerId,this.roomId,offer);
this.socket.emit('offer', {
roomId: this.roomId,
peerId: peerId,
offer: offer,
from: this.socket.id
});
} catch (error) {
console.error('Error creating and sending offer:', error);
}
}
}