Cross-pod (different-node) connection handling in the Socket.IO signaling handlers
CrowdStream runs multiple SFU pods/nodes and each room is owned by exactly one node
(tracked in Redis by the room coordinator: getRedisRoom → nodeId, compared against
config.instanceId).
Today the signaling handlers do not properly handle a socket that lands on a pod
which does not own the room:
registerBroadcaster.handler.ts — the guard exists but is stubbed with
//TODO: Implementation for different pod connections; it just throws
409 "Room belongs to another node".
registerViewer.handler.ts — the ownership guard is missing entirely; these
events operate on local room state with no node check.
This is the tracking issue for implementing real cross-pod handling (forward/proxy
signaling to the owning node, or redirect the client via sticky routing) at every
affected location. Sub-issues below.
Related: #36 (Sticky Sessions & Multi-Pod Signaling), #40 (Room→Node Placement Map in
Redis), #7 (Scalable Viewer Distribution with PipeTransport), #42 (Failover Test).
Sub-issues
registerBroadcaster.handler.ts — guard present, replace the 409 with real handling:
registerViewer.handler.ts — guard missing, add guard + handling:
Cross-pod (different-node) connection handling in the Socket.IO signaling handlers
CrowdStream runs multiple SFU pods/nodes and each room is owned by exactly one node
(tracked in Redis by the room coordinator:
getRedisRoom→nodeId, compared againstconfig.instanceId).Today the signaling handlers do not properly handle a socket that lands on a pod
which does not own the room:
registerBroadcaster.handler.ts— the guard exists but is stubbed with//TODO: Implementation for different pod connections; it just throws409 "Room belongs to another node".registerViewer.handler.ts— the ownership guard is missing entirely; theseevents operate on local room state with no node check.
This is the tracking issue for implementing real cross-pod handling (forward/proxy
signaling to the owning node, or redirect the client via sticky routing) at every
affected location. Sub-issues below.
Related: #36 (Sticky Sessions & Multi-Pod Signaling), #40 (Room→Node Placement Map in
Redis), #7 (Scalable Viewer Distribution with PipeTransport), #42 (Failover Test).
Sub-issues
registerBroadcaster.handler.ts— guard present, replace the 409 with real handling:getRouterRtpCapabilities(~L104)createBroadcasterTransport(~L161)connectBroadcasterTransport(~L249)produce(~L313)registerViewer.handler.ts— guard missing, add guard + handling:joinRoom(~L21)viewer:heartBeat(~L117)createViewerTransport(~L137)connectConsumerTransport(~L200)consume(~L229)pauseConsumer(~L268)resumeConsumer(~L290)