I need to enable compression for websocket communication (using socketio). I did this by setting the perMessageDeflate
to true
which worked fine in my development environment and on a staging server (verified with Wireshark). However, on our production server the websocket connection fails and socketio (v4.4.1) falls back to polling. Both use nginx as a reverse proxy with the same configuration. Chromium console shows
WebSocket connection to 'wss://***/ws-test/socket.io/?EIO=4&transport=websocket&sid=9P4EelJhF0CcxvwNAAAE' failed: Error during WebSocket handshake: Unexpected response code: 400
I created a minimal sample that shows the same behaviour. Nodejs app on the server:
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, {
perMessageDeflate: true
});
app.get('/', (req, res) => {
res.sendFile(__dirname '/index.html');
});
server.listen(3001, () => {
console.log('listening on *:3001');
});
Client:
...
<script src="socket.io/socket.io.js"></script>
<script>
var socketio_path = window.location.pathname 'socket.io';
var socket = io( { path: socketio_path } );
</script>
</body>
The error 400 seems to come from the nodejs server, not from nginx. I enabled all kinds of logging but couldn't find any related messages. Software versions are also reasonably close and up-to-date: nginx 1.18.0 on both (staging and production), nodejs 14.19.0/14.18.1 (staging/prod). Do you have any ideas that could help making this work on the production server?
CodePudding user response:
It turned out, the issue is the Azure Application Gateway used on the production server. When it's bypassed, the websocket connection (with perMessageDeflate
enabled) works fine.
Switching to a newer version of the Azure Application Gateway (v2 instead of v1) solved the issue in the end.