代理套接字 io 无法与 nginx、docker 上的节点连接

Posted

技术标签:

【中文标题】代理套接字 io 无法与 nginx、docker 上的节点连接【英文标题】:proxy socket io fails to connect with nginx, node on docker 【发布时间】:2018-10-30 02:11:42 【问题描述】:

我很难使用 nginx、node 和 react 在我的 docker 应用程序中连接 socket.io 实例。套接字请求保持未决状态,然后在一段时间后失败。我尝试了不同的配置以使 nginx 为节点服务器代理套接字请求,但没有成功。它曾经在 docker 之外工作,但现在我的套接字失败了。

这是我实际的 nginx 配置:

upstream frontend 
    least_conn;
    server client:8080;


upstream backend 
    least_conn;
    server server:8080;


server 
    listen 80;

    server_name localhost;

    location / 
        proxy_pass http://frontend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    

    location /api 
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    
    location /ws/ 
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    

这里是我的 docker compose 文件

version: '3'
   services:

     nginx:
       build:
         context: ../..
         dockerfile: ./dev-kit/docker/nginx/Dockerfile
       ports:
         - 8080:80
       links:
         - client
         - server

  client:
    build: ../../client
    ports:
      - 8088:8080
    volumes:
      - ../../client:/app:cached
    command: npm run start

  server:
    build: ../../server
    ports:
      - "8082:8080"
    volumes:
      - ../../server:/app:cached
    depends_on:
      - "mongo"

  mongo:
    image: "mongo"
    volumes:
      - /usr/local/var/mongodb/:/data/db
    ports:
      - "27017:27017"

这里是 express 上的服务器端:

const express           = require('express');
const app               = module.exports = express();
const http              = require('http').Server(app);

const bodyParser        = require('body-parser');
const io                = require('socket.io')(http);

const session           = require('express-session');
const MongoStore        = require('connect-mongo')(session);

const appInterface = process.env.HOST || '0.0.0.0';
const port = process.env.PORT || 8080;

app.use((req, res, next) => 
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested- With, Content-Type, Accept, x-access-token');
    res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE');
    next();
);

io.on('connection', (socket) => 
  console.log('one user connected !');
  socket.on('register', (userId) => 
    users[userId] = socket.id;
  );
);

// Start server
http.listen(port, appInterface.toString(), function (err)  
   console.log('[%s] Listening on http://localhost:%d', 
   app.settings.env, port); 
);

不幸的是,这永远不会执行,因为套接字 io 请求失败。

最后,我在客户端的 app.js 实例化了一个套接字 io 实例:

const socket = io('http://server:8080',  path: '/ws/socket.io' );
socket.emit('register', XXXX);

您的帮助将不胜感激。我尝试了很多不同的 nginx 配置来将套接字 io 请求代理到服务器,但没有成功。

【问题讨论】:

从您的服务器端代码中,您没有启动快速服务器(例如app.listen 您好,谢谢您的回答,我确实这样做了,我在帖子中编辑了我的编辑,对此感到抱歉,大家有什么想法吗? 您在 docker-compose 文件和 Nginx 上的端口映射配置。 您找到解决方案了吗? @Joelito docker-compose 说“server:8082”,但 nginx.conf 说“upstream backend server server:8080;” 【参考方案1】:

我相信您需要使用@sign 位置,如此处所述https://serverfault.com/questions/738452/what-does-the-at-sign-mean-in-nginx-location-blocks

所以 nginx.conf 看起来像这样:

location /socket.io 
    try_files $uri $uri/ @websocket;

...
location @websocket 
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

【讨论】:

以上是关于代理套接字 io 无法与 nginx、docker 上的节点连接的主要内容,如果未能解决你的问题,请参考以下文章

Nginx 与 docker:反向代理不起作用

通过反向代理服务器将socket.io android客户端连接到套接字服务器

使用 Nginx 的 socket.io 出现 CORS 错误

Docker Nginx 反向代理

Nginx反向代理docker容器局域网

无法使用 Nginx 反向代理连接到 Websocket 服务器