fix: corriger conflit upgrade WebSocket entre proxy LiveKit et audio-levels
AudioLevelsServer s'auto-attachait à l'événement 'upgrade' du serveur HTTP via la lib ws (server + path), en plus du listener manuel du proxy LiveKit. Pour toute connexion /livekit, les deux listeners s'exécutaient : le proxy LiveKit aboutissait bien côté upstream, mais le listener ws (path /audio-levels ne matchant pas) appelait abortHandshake(socket, 400) sur le même socket juste après, cassant la connexion côté client en HTTPS prod. AudioLevelsServer passe maintenant en noServer: true et expose handleUpgrade(), appelée par un dispatcher 'upgrade' unique dans server/index.js qui route explicitement par chemin (/livekit vs /audio-levels). Ajout de certs/ au .gitignore (clés privées SSL locales mkcert).
This commit is contained in:
@@ -55,3 +55,6 @@ server.log
|
|||||||
|
|
||||||
# Runtime files
|
# Runtime files
|
||||||
/tmp/ptt-live.pid
|
/tmp/ptt-live.pid
|
||||||
|
|
||||||
|
# Certificats SSL locaux (mkcert) - contiennent des clés privées
|
||||||
|
certs/
|
||||||
|
|||||||
+9
-11
@@ -520,28 +520,26 @@ async function start() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.5 Activer upgrade WebSocket pour proxy LiveKit
|
// 2.5 Démarrer WebSocket Audio Levels (même port que l'API)
|
||||||
// Important : gérer AVANT AudioLevelsServer
|
// noServer: true en interne, l'upgrade est dispatché ci-dessous
|
||||||
server.on('upgrade', (req, socket, head) => {
|
const audioLevelsServer = new AudioLevelsServer({ server });
|
||||||
log('info', `📡 WebSocket upgrade: ${req.url}`);
|
audioLevelsServer.start();
|
||||||
|
|
||||||
|
// 2.6 Dispatcher unique pour les upgrades WebSocket du port HTTP/HTTPS
|
||||||
|
// (proxy LiveKit et audio-levels partagent le même serveur, donc le même
|
||||||
|
// événement 'upgrade' : un seul listener doit trancher par chemin)
|
||||||
|
server.on('upgrade', (req, socket, head) => {
|
||||||
if (req.url.startsWith('/livekit')) {
|
if (req.url.startsWith('/livekit')) {
|
||||||
log('info', '🔀 Proxying to LiveKit on ws://localhost:7880');
|
|
||||||
// Réécrire l'URL pour enlever /livekit
|
|
||||||
req.url = req.url.replace(/^\/livekit/, '');
|
req.url = req.url.replace(/^\/livekit/, '');
|
||||||
livekitProxy.ws(req, socket, head);
|
livekitProxy.ws(req, socket, head);
|
||||||
} else if (req.url.startsWith('/audio-levels')) {
|
} else if (req.url.startsWith('/audio-levels')) {
|
||||||
log('debug', '📊 Audio levels WebSocket - handled by AudioLevelsServer');
|
audioLevelsServer.handleUpgrade(req, socket, head);
|
||||||
// AudioLevelsServer will handle this
|
|
||||||
} else {
|
} else {
|
||||||
log('warn', `⚠️ Unknown WebSocket path: ${req.url}`);
|
log('warn', `⚠️ Unknown WebSocket path: ${req.url}`);
|
||||||
socket.destroy();
|
socket.destroy();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2.6 Démarrer WebSocket Audio Levels (même port que l'API)
|
|
||||||
const audioLevelsServer = new AudioLevelsServer({ server });
|
|
||||||
audioLevelsServer.start();
|
|
||||||
const wsProtocol = ENABLE_HTTPS ? 'wss' : 'ws';
|
const wsProtocol = ENABLE_HTTPS ? 'wss' : 'ws';
|
||||||
log('info', `✓ WebSocket Audio Levels démarré sur ${wsProtocol}://${SERVER_HOST}:${SERVER_PORT}`);
|
log('info', `✓ WebSocket Audio Levels démarré sur ${wsProtocol}://${SERVER_HOST}:${SERVER_PORT}`);
|
||||||
|
|
||||||
|
|||||||
@@ -91,9 +91,11 @@ export class AudioLevelsServer extends EventEmitter {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
// Si un serveur HTTP est fourni, utiliser le même port (upgrade HTTP → WebSocket)
|
// Si un serveur HTTP est fourni, utiliser le même port (upgrade HTTP → WebSocket)
|
||||||
|
// noServer: true car l'upgrade est dispatché manuellement par server/index.js
|
||||||
|
// (un seul listener 'upgrade' partagé avec le proxy LiveKit, voir handleUpgrade())
|
||||||
// Sinon, créer un serveur WebSocket standalone sur son propre port
|
// Sinon, créer un serveur WebSocket standalone sur son propre port
|
||||||
const wsOptions = this.options.server
|
const wsOptions = this.options.server
|
||||||
? { server: this.options.server, path: '/audio-levels' }
|
? { noServer: true }
|
||||||
: { port: this.options.port };
|
: { port: this.options.port };
|
||||||
|
|
||||||
this.wss = new WebSocketServer(wsOptions);
|
this.wss = new WebSocketServer(wsOptions);
|
||||||
@@ -125,6 +127,16 @@ export class AudioLevelsServer extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Complète l'upgrade WebSocket pour une requête déjà identifiée comme
|
||||||
|
* ciblant ce serveur (voir le dispatcher 'upgrade' dans server/index.js)
|
||||||
|
*/
|
||||||
|
handleUpgrade(req, socket, head) {
|
||||||
|
this.wss.handleUpgrade(req, socket, head, (ws) => {
|
||||||
|
this.wss.emit('connection', ws, req);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gère une nouvelle connexion client
|
* Gère une nouvelle connexion client
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user