Files
snort/packages/app/src/webrtc/WebRTCPool.ts
Martti Malmi 1309937869 wip webrtc
2023-12-21 19:51:37 +02:00

86 lines
2.9 KiB
TypeScript

import {io, Socket} from 'socket.io-client';
import {WebRTCConnection} from '@/webrtc/WebRTCConnection';
import EventEmitter from "eventemitter3";
const MAX_CONNECTIONS = 5;
class WebRTCPool extends EventEmitter {
private signalingServer: Socket;
private peers: Map<string, WebRTCConnection> = new Map();
private configuration: RTCConfiguration;
private peerId: string;
constructor(serverUrl: string, configuration: RTCConfiguration = {}, peerId: string) {
super();
this.signalingServer = io(serverUrl);
this.configuration = configuration;
this.peerId = peerId;
this.registerSocketEvents();
}
private sayHello(): void {
this.signalingServer.emit('hello', this.peerId);
}
public send(data: any, recipients?: string[]): void {
this.peers.forEach(conn => {
if (!recipients || recipients.includes(conn.peerId)) {
try {
conn.send(typeof data === 'string' ? data : JSON.stringify(data));
} catch (e) {
console.error(e);
}
}
});
}
public createConnection(peerId: string): WebRTCConnection {
if (this.peers.size >= MAX_CONNECTIONS) {
throw new Error('Maximum connections reached');
}
const connection = new WebRTCConnection(this.signalingServer, this.configuration, peerId);
connection.on('event', (event: any) => this.emit('event', event));
this.peers.set(peerId, connection);
return connection;
}
private handleConnectionEvent(sender: string, action: (connection: WebRTCConnection) => Promise<void>): void {
if (sender === this.peerId || this.peers.size >= MAX_CONNECTIONS) return;
const connection = this.peers.get(sender) ?? this.createConnection(sender);
action(connection);
}
private registerSocketEvents(): void {
this.signalingServer.on('connect', () => {
console.log('Connected to signaling server');
this.sayHello();
});
this.signalingServer.on('offer', ({offer, sender}: { offer: RTCSessionDescriptionInit; sender: string }) => {
this.handleConnectionEvent(sender, async conn => await conn.handleOffer(offer));
});
this.signalingServer.on('answer', ({answer, sender}: { answer: RTCSessionDescriptionInit; sender: string }) => {
this.handleConnectionEvent(sender, async conn => await conn.handleAnswer(answer));
});
this.signalingServer.on('candidate', ({candidate, sender}: { candidate: RTCIceCandidateInit; sender: string }) => {
this.handleConnectionEvent(sender, conn => conn.handleCandidate(candidate));
});
this.signalingServer.on('hello', (sender: string) => {
console.log('Received hello from', sender);
this.handleConnectionEvent(sender, conn => conn.handleHello());
});
}
public close(): void {
console.log('closing pool');
this.signalingServer.close();
for (const conn of this.peers.values()) {
conn.close();
}
}
}
export default WebRTCPool;