Мне нужно включить сжатие для связи через веб-сокет (используя socketio). Я сделал это, установив perMessageDeflate
на true
, который отлично работал в моей среде разработки и на промежуточном сервере (проверено с помощью Wireshark). Однако на нашем производственном сервере соединение с веб-сокетом не удается, и socketio (v4.4.1) возвращается к опросу. Оба используют nginx в качестве обратного прокси с одинаковой конфигурацией. Консоль Chromium показывает
WebSocket connection to 'wss://***/ws-test/socket.io/?EIO=4&transport=websocket&sid=9P4EelJhF0CcxvwNAAAE' failed: Error during WebSocket handshake: Unexpected response code: 400
Я создал минимальный образец, который показывает такое же поведение. Приложение Nodejs на сервере:
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.info('listening on *:3001');
});
Клиент:
...
<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>
Ошибка 400, похоже, исходит от сервера nodejs, а не от nginx. Я включил все виды журналирования, но не смог найти никаких связанных сообщений. Версии программного обеспечения также достаточно близки и актуальны: nginx 1.18.0 на обоих (постановка и производство), nodejs 14.19.0/14.18.1 (постановка/производство). Есть ли у вас какие-либо идеи, которые могли бы помочь заставить это работать на рабочем сервере?
Выяснилось, что проблема заключается в шлюзе приложений Azure, используемом на рабочем сервере. Когда его обходят, соединение через веб-сокет (с включенным perMessageDeflate
) работает нормально.
Переход на более новую версию Шлюза приложений Azure (v2 вместо v1) в конце концов решил проблему.