feat: Make the TURN realm configurable via environment variable and ensure the viewer only reacts to the broadcaster's disconnection.
This commit is contained in:
@@ -10,6 +10,7 @@ services:
|
|||||||
- BROADCASTER_PASSWORD=${BROADCASTER_PASSWORD}
|
- BROADCASTER_PASSWORD=${BROADCASTER_PASSWORD}
|
||||||
- TURN_USER=${TURN_USER}
|
- TURN_USER=${TURN_USER}
|
||||||
- TURN_PASSWORD=${TURN_PASSWORD}
|
- TURN_PASSWORD=${TURN_PASSWORD}
|
||||||
|
- TURN_REALM=${TURN_REALM}
|
||||||
|
|
||||||
coturn:
|
coturn:
|
||||||
image: coturn/coturn:latest
|
image: coturn/coturn:latest
|
||||||
@@ -20,6 +21,6 @@ services:
|
|||||||
--log-file=stdout
|
--log-file=stdout
|
||||||
--min-port=49152
|
--min-port=49152
|
||||||
--max-port=49252
|
--max-port=49252
|
||||||
--realm=yourdomain.com
|
--realm=${TURN_REALM}
|
||||||
--user=${TURN_USER}:${TURN_PASSWORD}
|
--user=${TURN_USER}:${TURN_PASSWORD}
|
||||||
--stale-nonce
|
--stale-nonce
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ const remoteVideo = document.getElementById('remoteVideo');
|
|||||||
const overlay = document.getElementById('overlay');
|
const overlay = document.getElementById('overlay');
|
||||||
|
|
||||||
let peerConnection;
|
let peerConnection;
|
||||||
|
let broadcasterPeerId = null; // Track who the broadcaster is
|
||||||
|
|
||||||
// Fetch TURN credentials dynamically from the server
|
// Fetch TURN credentials dynamically from the server
|
||||||
const turnHost = window.location.hostname;
|
const turnHost = window.location.hostname;
|
||||||
@@ -28,6 +29,9 @@ fetch('/turn-config')
|
|||||||
.catch(e => console.error('Failed to load TURN config:', e));
|
.catch(e => console.error('Failed to load TURN config:', e));
|
||||||
|
|
||||||
socket.on('offer', (id, description) => {
|
socket.on('offer', (id, description) => {
|
||||||
|
// Track the broadcaster's socket ID so we only react to THEIR disconnect
|
||||||
|
broadcasterPeerId = id;
|
||||||
|
|
||||||
// Close any existing connection before creating a new one
|
// Close any existing connection before creating a new one
|
||||||
if (peerConnection) {
|
if (peerConnection) {
|
||||||
peerConnection.close();
|
peerConnection.close();
|
||||||
@@ -51,11 +55,9 @@ socket.on('offer', (id, description) => {
|
|||||||
peerConnection.oniceconnectionstatechange = () => {
|
peerConnection.oniceconnectionstatechange = () => {
|
||||||
console.log('ICE state:', peerConnection.iceConnectionState);
|
console.log('ICE state:', peerConnection.iceConnectionState);
|
||||||
if (peerConnection.iceConnectionState === 'failed') {
|
if (peerConnection.iceConnectionState === 'failed') {
|
||||||
// Try ICE restart before giving up
|
|
||||||
console.log('ICE failed, attempting restart...');
|
console.log('ICE failed, attempting restart...');
|
||||||
peerConnection.restartIce();
|
peerConnection.restartIce();
|
||||||
} else if (peerConnection.iceConnectionState === 'disconnected') {
|
} else if (peerConnection.iceConnectionState === 'disconnected') {
|
||||||
// Wait briefly then check if it recovered
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (peerConnection && peerConnection.iceConnectionState === 'disconnected') {
|
if (peerConnection && peerConnection.iceConnectionState === 'disconnected') {
|
||||||
console.log('ICE still disconnected, attempting restart...');
|
console.log('ICE still disconnected, attempting restart...');
|
||||||
@@ -114,11 +116,15 @@ socket.on('broadcaster', () => {
|
|||||||
socket.emit('viewer');
|
socket.emit('viewer');
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('disconnectPeer', () => {
|
// CRITICAL: Only react to the BROADCASTER's disconnect, not other viewers
|
||||||
|
socket.on('disconnectPeer', (id) => {
|
||||||
|
if (id !== broadcasterPeerId) return; // Ignore other viewers disconnecting
|
||||||
|
|
||||||
if (peerConnection) {
|
if (peerConnection) {
|
||||||
peerConnection.close();
|
peerConnection.close();
|
||||||
peerConnection = null;
|
peerConnection = null;
|
||||||
}
|
}
|
||||||
|
broadcasterPeerId = null;
|
||||||
remoteVideo.classList.remove('active');
|
remoteVideo.classList.remove('active');
|
||||||
remoteVideo.srcObject = null;
|
remoteVideo.srcObject = null;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user