Why does running two websocket servers with different paths cause the client to get an "invalid frame header" and disconnect?

Viewed 199

This is the server code

import path from 'path';
import http from 'http';
import { dirname } from 'path';
import { fileURLToPath } from 'url';
import express from 'express';
import WebSocket from 'ws';
const __dirname = dirname(fileURLToPath(import.meta.url));
const app = express();
console.log(__dirname)
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname + '/v3client/html/botkill.html'));
})
let httpServer = http.createServer(app).listen(80, () => {
    console.log('listening');
});
global.hServer = httpServer;
let wss = new WebSocket.Server({ server: global.hServer, path: '/based' });
wss.on('listening', () => {
    console.log(`listening with path /based`);
});
function heartbeat() {
    this.isAlive = true;
}
wss.on('connection', (socket) => {
    console.log('connected')
    socket.isAlive = true;
    socket.on('pong', heartbeat);
    socket.on('close', () => {
        console.log('disconnected')
    });
});
const pingPong = setInterval(() => {
    wss.clients.forEach((ws) => {
        if (ws.isAlive === false) return ws.terminate();
        ws.isAlive = false;
        ws.ping();
    });
}, 30000);
new WebSocket.Server({ server: global.hServer, path: '/notsobased' });

this is botkill.html

<script>
    let ws = new WebSocket('ws://localhost/based');
    ws.onopen = () => {
        console.log('open');
    };
    ws.onclose = async () => {
        console.log('disconnected');
    };
    ws.onerror = async (e) => {
        console.log(e, 'error');
    };
    ws.onmessage = function (e) {
        return false;
    };
</script>

When I open the webpage it immediately disconnects, but when I comment out the last line of the server code it gives me the error "invalid frame header". This is the smallest I could make the example, but I learned this recently when I tried to use two separate websocket servers on different paths, which seems to not work but I can't seem to figure out why. Also, it still immediately disconnects with https but it doesn't even have an error on the client.

1 Answers

So with a bit of searching for related topics I learned that the problem was that the websocket servers were both attached to the http server, rather than the http server itself handing connections to a websocket server. by using the http.Server.on('upgrade', ...) and Websocket.Server.handleUpgrade with the two servers I got it working. Sorry for the inconvience!

Related