Балансировка нагрузки Nginx не обновляет порт WebSocket до node.js - PullRequest
0 голосов
/ 05 апреля 2020

Я пытаюсь настроить nginx веб-сервер с открытым исходным кодом для локальной сети. Идея состоит в том, чтобы использовать nginx для балансировки нагрузки HTTP, HTTPS и WebSocket traffi c до node.js веб-серверов. Это распространенный сценарий, но я не мог заставить его работать. Все источники Inte rnet, к которым я пришел, говорили более или менее одинаково.

Мой nginx файл конфигурации является почти копией базового c файла балансировки нагрузки, который указан в https://docs.nginx.com/nginx/deployment-guides/load-balance-third-party/node-js/. Проблема в том, что порт WebSocket не обновляется. По какой-то причине происходит перенаправление HTTP 302, в то время как все остальное работает.

Клиент печатает ошибку

WebSocket connection to 'wss://192.168.10.2/' failed: Error during WebSocket handshake: Unexpected response code: 302

Все серверы работают на одном компьютере и используют один и тот же IP-адрес. Один сервер узла работает как положено. Если кто-то может написать слово или поделиться ссылкой, это будет высоко ценится. Nginx версия 1.17.9 и node.js версия 13.11.0. Какой-то код:

 # ############################################################
 # nginxTest.conf
 # ############################################################
proxy_cache_path /tmp/NGINX_TEST_cache/ keys_zone=hahaha:10m;

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

upstream nodeTest {
    ip_hash;

    server 192.168.10.2:8000;
    # More servers with the same IP and different port.
}

server {
    listen 80;
    server_name 192.168.10.2;

    location / {    
        return 301 https://$server_name$request_uri;
    } 
}

server {
    listen 443 ssl http2;
    server_name 192.168.10.2;

    ssl_certificate     /etc/nginx/ssl/cert.pem;
    ssl_certificate_key  /etc/nginx/ssl/key.pem;
    ssl_session_cache   shared:SSL:1m;
    ssl_prefer_server_ciphers  on;

    # Return a 302 Redirect to the /webapp/ directory
    # when user requests /
    location = / {
        return 302 /webapp/;
    }

    # A location block is needed per URI group
    location /webapp/ {
        proxy_pass https://nodeTest/;
        proxy_cache hahaha;
    }

    # WebSocket configuration
    location /wstunnel/ {
        proxy_pass https://nodeTest/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    proxy_headers_hash_max_size 512;
    proxy_headers_hash_bucket_size 128;
    }
}
# ############################################################
# node.js server file
# ############################################################
const https = require('https');
const express = require('express');
const app = express();
const path = require('path');
const fs = require('fs');
const WebSocket = require('ws');
const webServerPort = process.env.NODE_PORT || 443;
const credentials = {
    key: fs.readFileSync('/etc/nginx/ssl//key.pem', 'utf8'),
    cert: fs.readFileSync('/etc/nginx/ssl/cert.pem', 'utf8')
};
// 
const httpsServer = new https.createServer(credentials, app);
const wss = new WebSocket.Server({server: httpsServer});

// //////////////////////////////////////////////////
app.use(express.static(path.join(__dirname, 'public')));

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname,'views/index.html'));
});

// error handling - from https://expressjs.com/en/guide/error-handling.html
app.use( (err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send('Oops! Something went wrong.');
});

// //////////////////////////////////////////////////
// WebSockets
wss.on('connection', ws => {
    ws.send(JSON.stringify({type: 'serverMsg', text: "Hallo form web server through WebScockets! You've just connected!"}));

    // catch ws errors
    ws.onerror = err => {console.log("Something went wrong in a WebSocket")};

    ws.on('message', msg => {
    ws.send(JSON.stringify({type: 'wsMsg', text: 'Websocket server reply: good work!'}));
    });
});

// //////////////////////////////////////////////////
httpsServer.listen(webServerPort, () => console.log('Server listening on port: ', webServerPort));

# ############################################################
# index.html
# ############################################################
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
    body {
        background: #293f50;
        color: #888;
    }
    </style>
    <title>nginx test</title>
  </head>
  <body>
    <h1>nginx test</h1>
    <p id="serverMsg"></p>
    <p id="wsMsg"></p>
    <script>
      const socket = new WebSocket('wss:192.168.10.2');

         socket.onmessage = message => {
         const msg = JSON.parse(message.data);

         document.getElementById(msg.type).textContent = msg.text;
         };

         socket.onopen = () => {
         // send message to web server
         socket.send('Hallo from client. Have a chat?');
         };
         socket.onerror = () => console.log('ERROR in WebSocket');
    </script>
  </body>
</html>
# ############################################################

Спасибо!

...