Fix WebSocket upgrade handling to preserve Next.js HMR handlers
- Save existing upgrade listeners before adding our own - Call existing listeners for non-matching paths to allow Next.js HMR - Only handle /ws/script-execution ourselves - This ensures Next.js can handle its own WebSocket upgrades for HMR
This commit is contained in:
46
server.js
46
server.js
@@ -79,16 +79,27 @@ class ScriptExecutionHandler {
|
|||||||
* @param {import('http').Server} server
|
* @param {import('http').Server} server
|
||||||
*/
|
*/
|
||||||
constructor(server) {
|
constructor(server) {
|
||||||
// Create WebSocketServer attached to server with path filter
|
// Create WebSocketServer without attaching to server
|
||||||
// The path option should ensure it only handles /ws/script-execution
|
// We'll handle upgrades manually to avoid interfering with Next.js HMR
|
||||||
this.wss = new WebSocketServer({
|
this.wss = new WebSocketServer({
|
||||||
server,
|
noServer: true
|
||||||
path: '/ws/script-execution'
|
|
||||||
});
|
});
|
||||||
this.activeExecutions = new Map();
|
this.activeExecutions = new Map();
|
||||||
this.db = getDatabase();
|
this.db = getDatabase();
|
||||||
this.setupWebSocket();
|
this.setupWebSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle WebSocket upgrade for our endpoint
|
||||||
|
* @param {import('http').IncomingMessage} request
|
||||||
|
* @param {import('net').Socket} socket
|
||||||
|
* @param {Buffer} head
|
||||||
|
*/
|
||||||
|
handleUpgrade(request, socket, head) {
|
||||||
|
this.wss.handleUpgrade(request, socket, head, (ws) => {
|
||||||
|
this.wss.emit('connection', ws, request);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse Container ID from terminal output
|
* Parse Container ID from terminal output
|
||||||
@@ -1187,6 +1198,33 @@ app.prepare().then(() => {
|
|||||||
|
|
||||||
// Create WebSocket handlers
|
// Create WebSocket handlers
|
||||||
const scriptHandler = new ScriptExecutionHandler(httpServer);
|
const scriptHandler = new ScriptExecutionHandler(httpServer);
|
||||||
|
|
||||||
|
// Handle WebSocket upgrades manually to avoid interfering with Next.js HMR
|
||||||
|
// We need to preserve Next.js's upgrade handlers and call them for non-matching paths
|
||||||
|
// Save any existing upgrade listeners (Next.js might have set them up)
|
||||||
|
const existingUpgradeListeners = httpServer.listeners('upgrade').slice();
|
||||||
|
httpServer.removeAllListeners('upgrade');
|
||||||
|
|
||||||
|
// Add our upgrade handler that routes based on path
|
||||||
|
httpServer.on('upgrade', (request, socket, head) => {
|
||||||
|
const parsedUrl = parse(request.url || '', true);
|
||||||
|
const { pathname } = parsedUrl;
|
||||||
|
|
||||||
|
if (pathname === '/ws/script-execution') {
|
||||||
|
// Handle our custom WebSocket endpoint
|
||||||
|
scriptHandler.handleUpgrade(request, socket, head);
|
||||||
|
} else {
|
||||||
|
// For all other paths (including Next.js HMR), call existing listeners
|
||||||
|
// This allows Next.js to handle its own WebSocket upgrades
|
||||||
|
for (const listener of existingUpgradeListeners) {
|
||||||
|
try {
|
||||||
|
listener.call(httpServer, request, socket, head);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error in upgrade listener:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
// Note: TerminalHandler removed as it's not being used by the current application
|
// Note: TerminalHandler removed as it's not being used by the current application
|
||||||
|
|
||||||
httpServer
|
httpServer
|
||||||
|
|||||||
Reference in New Issue
Block a user