Search code examples
node.jssocket.iohttp-proxyvhostshttp-proxy-middleware

Socket.IO on Subdomain vhost and proxy


I'm trying to proxy socket.example.com:4000 to a websocket server mydomain.com:3000 but the client can also connect to the server through *.example.com:4000, It's like vhost has no effect and the proxy configuration is set globally. I don't want other subdomains be proxied.

i use vhost and http-proxy-middleware

const options = {
    target: 'http://example.com:3000',
    changeOrigin: true,
    ws: true
};
    
const wsProxy = createProxyMiddleware(options);

app.use(vhost('socket.example.com', wsProxy));

Solution

  • I didn't need vhost nor http-proxy-middleware. i used http-proxy and some vanilla javascript.

    import httpProxy from 'http-proxy';
    
    const proxy = httpProxy.createProxyServer({
        target: {
            host: 'example.com',
            port: 4001
        }
    });
    
    server.on('upgrade', (req, socket, head) => {
        const domain = req.headers.host;
        const host = domain.split(':')[0];
    
        if (host === 'socket.example.com') {
            proxy.ws(req, socket, head);
        } else {
            socket.destroy();
        }
    });
    

    ##Update## Running on the same server without proxy or dedicated websocket server.

    import { Server } from "socket.io";
    
    const app = express();
    const server = http.createServer(app);
    
    const io = new Server(server, {
        allowRequest: (req, fn) => {
            const domain = req.headers.host;
            const host = domain.split(':')[0];
    
            fn(null, host === `socket.example.com`);
        }
    });
    
    io.on('connection', (socket) => {
        console.log('a user connected');
    });