Skip to content
This repository was archived by the owner on Jun 28, 2026. It is now read-only.

Commit 52f1de7

Browse files
committed
refactor(sfu): drop SocketHandler class boilerplate
1 parent 762d364 commit 52f1de7

17 files changed

Lines changed: 245 additions & 320 deletions

sfu-server/src/server/SocketHandlerManager.ts

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,21 @@ import type { MediasoupManager } from '../mediasoup/MediasoupManager';
33
import type { ClientToServerEvents, ServerToClientEvents } from '../types';
44
import { RateLimiter } from '../utils/rateLimiter';
55
import type { AuthManager } from './AuthManager';
6-
import {
7-
AuthHandlers,
8-
ChatHandlers,
9-
ConsumerHandlers,
10-
DisconnectHandlers,
11-
ErrorHandlers,
12-
HostControlHandlers,
13-
MediaControlHandlers,
14-
ProducerHandlers,
15-
RaiseHandHandlers,
16-
ReactionHandlers,
17-
RoomJoinHandlers,
18-
RoomQueryHandlers,
19-
ScreenShareHandlers,
20-
WebRtcTransportHandlers,
21-
} from './handlers';
22-
import type { HandlerDeps, SocketHandler } from './handlers/Handler';
6+
import { registerAuthHandlers } from './handlers/AuthHandlers';
7+
import { registerChatHandlers } from './handlers/ChatHandlers';
8+
import { registerConsumerHandlers } from './handlers/ConsumerHandlers';
9+
import { registerDisconnectHandlers } from './handlers/DisconnectHandlers';
10+
import { registerErrorHandlers } from './handlers/ErrorHandlers';
11+
import type { HandlerDeps } from './handlers/Handler';
12+
import { registerHostControlHandlers } from './handlers/HostControlHandlers';
13+
import { registerMediaControlHandlers } from './handlers/MediaControlHandlers';
14+
import { registerProducerHandlers } from './handlers/ProducerHandlers';
15+
import { registerRaiseHandHandlers } from './handlers/RaiseHandHandlers';
16+
import { registerReactionHandlers } from './handlers/ReactionHandlers';
17+
import { registerRoomJoinHandlers } from './handlers/RoomJoinHandlers';
18+
import { registerRoomQueryHandlers } from './handlers/RoomQueryHandlers';
19+
import { registerScreenShareHandlers } from './handlers/ScreenShareHandlers';
20+
import { registerWebRtcTransportHandlers } from './handlers/WebRtcTransportHandlers';
2321
import { RoomRegistry } from './RoomRegistry';
2422

2523
export class SocketHandlerManager {
@@ -28,7 +26,7 @@ export class SocketHandlerManager {
2826
private authManager: AuthManager;
2927
private registry: RoomRegistry;
3028
private rateLimiter: RateLimiter;
31-
private handlers: SocketHandler[];
29+
private registerHandlers: ((socket: import('socket.io').Socket) => void)[];
3230

3331
constructor(
3432
io: Server<ClientToServerEvents, ServerToClientEvents>,
@@ -49,21 +47,21 @@ export class SocketHandlerManager {
4947
rateLimiter: this.rateLimiter,
5048
};
5149

52-
this.handlers = [
53-
new AuthHandlers(deps),
54-
new RoomJoinHandlers(deps),
55-
new RoomQueryHandlers(deps),
56-
new WebRtcTransportHandlers(deps),
57-
new ProducerHandlers(deps),
58-
new ConsumerHandlers(deps),
59-
new MediaControlHandlers(deps),
60-
new HostControlHandlers(deps),
61-
new ScreenShareHandlers(deps),
62-
new ChatHandlers(deps),
63-
new ReactionHandlers(deps),
64-
new RaiseHandHandlers(deps),
65-
new DisconnectHandlers(deps),
66-
new ErrorHandlers(deps),
50+
this.registerHandlers = [
51+
registerAuthHandlers(deps),
52+
registerRoomJoinHandlers(deps),
53+
registerRoomQueryHandlers(deps),
54+
registerWebRtcTransportHandlers(deps),
55+
registerProducerHandlers(deps),
56+
registerConsumerHandlers(deps),
57+
registerMediaControlHandlers(deps),
58+
registerHostControlHandlers(deps),
59+
registerScreenShareHandlers(deps),
60+
registerChatHandlers(deps),
61+
registerReactionHandlers(deps),
62+
registerRaiseHandHandlers(deps),
63+
registerDisconnectHandlers(deps),
64+
registerErrorHandlers(deps),
6765
];
6866

6967
this.mediasoup.onNetworkQualityUpdate((roomId, peerId, quality) => {
@@ -93,8 +91,8 @@ export class SocketHandlerManager {
9391
next();
9492
});
9593

96-
for (const handler of this.handlers) {
97-
handler.register(socket);
94+
for (const register of this.registerHandlers) {
95+
register(socket);
9896
}
9997
});
10098
}
Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import type { Socket } from 'socket.io';
22
import { loggers } from '../../utils/logger';
3-
import type { HandlerDeps, SocketHandler } from './Handler';
3+
import type { HandlerDeps } from './Handler';
44

5-
export class AuthHandlers implements SocketHandler {
6-
register(socket: Socket): void {
5+
export function registerAuthHandlers(deps: HandlerDeps) {
6+
return (socket: Socket) => {
77
socket.on('auth:update_token', (data, callback) => {
88
try {
99
const token = typeof data?.token === 'string' ? data.token : null;
@@ -12,7 +12,7 @@ export class AuthHandlers implements SocketHandler {
1212
return;
1313
}
1414

15-
this.deps.authManager.updateSocketToken(socket, token);
15+
deps.authManager.updateSocketToken(socket, token);
1616
callback({ success: true });
1717
} catch (error) {
1818
const message = (error as Error).message || 'Token update failed';
@@ -22,13 +22,8 @@ export class AuthHandlers implements SocketHandler {
2222
message,
2323
);
2424
callback({ success: false, error: message });
25-
this.deps.authManager.triggerTokenExpiry(
26-
socket,
27-
'invalid_refresh_token',
28-
);
25+
deps.authManager.triggerTokenExpiry(socket, 'invalid_refresh_token');
2926
}
3027
});
31-
}
32-
33-
constructor(private deps: HandlerDeps) {}
28+
};
3429
}

sfu-server/src/server/handlers/ChatHandlers.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
import type { Socket } from 'socket.io';
22
import type { ChatMessage } from '../../types';
33
import { loggers } from '../../utils/logger';
4-
import type { HandlerDeps, SocketHandler } from './Handler';
4+
import type { HandlerDeps } from './Handler';
55

6-
export class ChatHandlers implements SocketHandler {
7-
constructor(private deps: HandlerDeps) {}
8-
9-
register(socket: Socket): void {
6+
export function registerChatHandlers(deps: HandlerDeps) {
7+
return (socket: Socket) => {
108
socket.on('chat:toggle_restriction', (data) => {
119
try {
12-
this.deps.authManager.ensureFullAccess(socket);
10+
deps.authManager.ensureFullAccess(socket);
1311
const roomId = socket.roomId;
1412

1513
if (!roomId || (!socket.isHost && !socket.isCohost)) return;
1614
const isRestricted = Boolean(data.enabled);
17-
this.deps.registry.setHostOnlyChat(roomId, isRestricted);
15+
deps.registry.setHostOnlyChat(roomId, isRestricted);
1816

19-
this.deps.registry.emitToFullAccessParticipants(
17+
deps.registry.emitToFullAccessParticipants(
2018
roomId,
2119
'chat:restriction_updated',
2220
{ enabled: isRestricted },
@@ -28,7 +26,7 @@ export class ChatHandlers implements SocketHandler {
2826

2927
socket.on('chat:send', (data = {}) => {
3028
try {
31-
this.deps.authManager.ensureFullAccess(socket);
29+
deps.authManager.ensureFullAccess(socket);
3230
const roomId = socket.roomId;
3331
const text = (
3432
typeof data.message === 'string' ? data.message : ''
@@ -44,7 +42,7 @@ export class ChatHandlers implements SocketHandler {
4442
}
4543

4644
if (
47-
this.deps.registry.isHostOnlyChat(roomId) &&
45+
deps.registry.isHostOnlyChat(roomId) &&
4846
!socket.isHost &&
4947
!socket.isCohost
5048
) {
@@ -65,7 +63,7 @@ export class ChatHandlers implements SocketHandler {
6563
};
6664
if (data.clientId) payload.clientId = String(data.clientId);
6765

68-
this.deps.registry.emitToFullAccessParticipants(
66+
deps.registry.emitToFullAccessParticipants(
6967
roomId,
7068
'chat:message',
7169
payload,
@@ -77,5 +75,5 @@ export class ChatHandlers implements SocketHandler {
7775
);
7876
}
7977
});
80-
}
78+
};
8179
}

sfu-server/src/server/handlers/ConsumerHandlers.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import type { Socket } from 'socket.io';
22
import { loggers } from '../../utils/logger';
3-
import type { HandlerDeps, SocketHandler } from './Handler';
3+
import type { HandlerDeps } from './Handler';
44

5-
export class ConsumerHandlers implements SocketHandler {
6-
constructor(private deps: HandlerDeps) {}
7-
8-
register(socket: Socket): void {
5+
export function registerConsumerHandlers(deps: HandlerDeps) {
6+
return (socket: Socket) => {
97
socket.on('create_consumer', async (data, callback) => {
108
try {
11-
this.deps.authManager.ensureFullAccess(socket);
9+
deps.authManager.ensureFullAccess(socket);
1210
const { transportId, producerId, rtpCapabilities } = data;
13-
const consumer = await this.deps.mediasoup.createConsumer(
11+
const consumer = await deps.mediasoup.createConsumer(
1412
transportId,
1513
producerId,
1614
rtpCapabilities,
@@ -28,9 +26,9 @@ export class ConsumerHandlers implements SocketHandler {
2826

2927
socket.on('close_consumer', async (data, callback) => {
3028
try {
31-
this.deps.authManager.ensureFullAccess(socket);
29+
deps.authManager.ensureFullAccess(socket);
3230
const { consumerId } = data;
33-
await this.deps.mediasoup.closeConsumer(consumerId);
31+
await deps.mediasoup.closeConsumer(consumerId);
3432

3533
callback({ success: true });
3634
} catch (error) {
@@ -54,7 +52,7 @@ export class ConsumerHandlers implements SocketHandler {
5452
const width = Math.round(data.width);
5553
const height = Math.round(data.height);
5654

57-
const result = await this.deps.mediasoup.updateConsumerPreferences({
55+
const result = await deps.mediasoup.updateConsumerPreferences({
5856
consumerId,
5957
visible,
6058
width,
@@ -70,5 +68,5 @@ export class ConsumerHandlers implements SocketHandler {
7068
callback({ success: false, error: (error as Error).message });
7169
}
7270
});
73-
}
71+
};
7472
}
Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import type { Socket } from 'socket.io';
22
import { loggers } from '../../utils/logger';
3-
import type { HandlerDeps, SocketHandler } from './Handler';
3+
import type { HandlerDeps } from './Handler';
44
import { isRealParticipant } from './utils';
55

6-
export class DisconnectHandlers implements SocketHandler {
7-
constructor(private deps: HandlerDeps) {}
8-
9-
register(socket: Socket): void {
6+
export function registerDisconnectHandlers(deps: HandlerDeps) {
7+
return (socket: Socket) => {
108
socket.on('disconnect', async () => {
11-
this.deps.authManager.cleanupSocket(socket);
9+
deps.authManager.cleanupSocket(socket);
1210

1311
loggers.socketHandler.info(
1412
'Disconnected: %s (User: %s, Scope: %s)',
@@ -22,22 +20,22 @@ export class DisconnectHandlers implements SocketHandler {
2220

2321
if (roomId && participantId) {
2422
try {
25-
this.deps.registry.removeSocket(roomId, socket.id);
23+
deps.registry.removeSocket(roomId, socket.id);
2624

2725
if (socket.scope === 'full') {
28-
await this.deps.mediasoup.removePeer(roomId, participantId);
26+
await deps.mediasoup.removePeer(roomId, participantId);
2927

3028
if (isRealParticipant(participantId)) {
31-
this.deps.registry.emitParticipantEvent(
29+
deps.registry.emitParticipantEvent(
3230
roomId,
3331
'participant_left',
3432
participantId,
3533
);
3634
}
3735

38-
if (this.deps.registry.hasRaisedHand(roomId, participantId)) {
39-
this.deps.registry.clearRaisedHand(roomId, participantId);
40-
this.deps.registry.emitToFullAccessParticipants(
36+
if (deps.registry.hasRaisedHand(roomId, participantId)) {
37+
deps.registry.clearRaisedHand(roomId, participantId);
38+
deps.registry.emitToFullAccessParticipants(
4139
roomId,
4240
'hand_raised',
4341
{
@@ -55,14 +53,14 @@ export class DisconnectHandlers implements SocketHandler {
5553
);
5654
}
5755

58-
if (this.deps.registry.isEmpty(roomId)) {
59-
this.deps.registry.cleanupRoom(roomId);
60-
this.deps.mediasoup.closeRoom(roomId);
56+
if (deps.registry.isEmpty(roomId)) {
57+
deps.registry.cleanupRoom(roomId);
58+
deps.mediasoup.closeRoom(roomId);
6159
}
6260
} catch (error) {
6361
loggers.socketHandler.error('Error handling disconnect: %s', error);
6462
}
6563
}
6664
});
67-
}
65+
};
6866
}
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import type { Socket } from 'socket.io';
22
import { loggers } from '../../utils/logger';
3-
import type { HandlerDeps, SocketHandler } from './Handler';
3+
import type { HandlerDeps } from './Handler';
44

5-
export class ErrorHandlers implements SocketHandler {
6-
constructor(_deps: HandlerDeps) {}
7-
8-
register(socket: Socket): void {
5+
export function registerErrorHandlers(_deps: HandlerDeps) {
6+
return (socket: Socket) => {
97
socket.on('error', (error) => {
108
loggers.socketHandler.error('Socket error for %s: %s', socket.id, error);
119
socket.emit('sfu_error', {
1210
error: (error as Error).message,
1311
timestamp: new Date().toISOString(),
1412
});
1513
});
16-
}
14+
};
1715
}

sfu-server/src/server/handlers/Handler.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,3 @@ export interface HandlerDeps {
2323
authManager: AuthManager;
2424
rateLimiter: RateLimiter;
2525
}
26-
27-
export interface SocketHandler {
28-
register(socket: Socket): void;
29-
}

0 commit comments

Comments
 (0)