Nginx + Socket.io + Nodejs:如何在自訂路徑上設定 socket.io

Nginx + Socket.io + Nodejs:如何在自訂路徑上設定 socket.io
Ubuntu 22.04
Nginx: 1.23.2
Nodejs: 12.22.9
Socket.io: 2.0.3

我在 Apache2 中建立了一個基本的 Node.js 聊天室,但我將所有內容都遷移到了 Ngnix,並且在嘗試讓聊天室再次工作時遇到了問題。我試圖讓我的聊天應用程式作為目錄/cnode2/而不是根 URL 工作(因為我有其他應用程式)。

當我嘗試載入頁面時,出現以下錯誤:

WebSocket connection to 'wss://www.*****.com/socket.io/?EIO=3&transport=websocket' failed: 
r.doOpen @ websocket.js:112
r.open @ transport.js:80
r.open @ socket.js:245
r @ socket.js:119
r @ socket.js:28
r.open.r.connect @ manager.js:226
r @ manager.js:69
r @ manager.js:37
r @ index.js:60
(anonymous) @ (index):539
cmain.js:160 connect_error: {"type":"TransportError","description":{"isTrusted":true}}

看來這一定是一個非常簡單的修復,就像它可能應該連接到“ wss://www.*****.com/cnode2/socket.io/”(或者也許不是)?我不太清楚如何正確配置所有內容或在哪裡配置它。這是我的配置:

包.json:

{
  "name": "chat",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "nodejs app"
  },
  "dependencies": {
    "cluster": "^0.7.7",
    "domain": "0.0.1",
    "express": "^4.16.3",
    "helmet": "^3.12.0",
    "mongoose": "^5.0.0",
    "mysql": "^2.15.0",
    "os": "^0.1.1",
    "package.json": "^2.0.1",
    "redis": "^2.8.0",
    "socket.io": "^2.0.3",
    "socket.io-redis": "^5.2.0",
    "sticky-session": "^1.1.2"
  }
}

Ngnix 配置:

server {
    server_name www.********.com;
    root /home/********/********.com;
    charset utf-8;

    #listen [::]:443 http2 ssl; # managed by Certbot

    rewrite ^([^.]*[^/])$ $1/ permanent;

    location ~ \.php$ {
      fastcgi_pass unix:/var/run/php/php8.1-fpm-******.sock;
      fastcgi_index index.php;
      fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
      include fastcgi_params;
    }

    location /cnode2/ {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $host;

      proxy_pass http://localhost:3000;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate ***; # managed by Certbot
    ssl_certificate_key ***; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

客戶端連線IO-網頁中的程式碼:

<script src="https://www.*******.com/cnode2/socket.io.js"></script>
<script>
  var socket = io('https://www.*********.com/cnode2', {resources: "/cnode2/socket.io", transports: ['websocket','polling']});
</script>

伺服器端 app.js 設定:

var http = require('http'),
  express = require('express'),
  cluster = require('cluster'),
  net = require('net'),
  io = require('socket.io'),
  io_redis = require('socket.io-redis'),
  sticky = require('sticky-session'),
  os = require('os'),
  helmet = require('helmet'),
  app = new express;
  app.use(helmet());
  var server = http.createServer(app, function(req, res) {
    console.log('launch server');
    res.end('worker: '+cluster.worker.id);
  });

var numCPUs = os.cpus().length;
  console.log('num CPUs: '+numCPUs);

if(!sticky.listen(server, 3000)) {
  for(var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  server.once('listening', function() {
    console.log('server started on 3000 port');
  });
}
else {
  console.log('spawn worker');
  var io = io(server, {path: '/cnode2', transports: ['websocket', 'polling']});
....
}

答案1

在我把頭撞到牆上並經歷了一點嘗試/錯誤的運氣之後,我透過將客戶端腳本更改為:

<script>
  var socket = io('https://www.*************.com', {path: "/cnode2", transports: ['websocket','polling']});
</script>

似乎“路徑”必須與伺服器端應用程式配置中設定的“路徑”相符。

相關內容