【问题标题】:Establish web-socket communication with react and express (nginx, docker)使用 react 和 express 建立 web-socket 通信(nginx、docker)
【发布时间】:2019-03-19 09:36:06
【问题描述】:

尝试设置 websocket 连接,当我在本地主机环境中时它工作正常,但是一旦我设置了 docker 环境,客户端(react)很难与 express 建立 web-socket 通信。我应该定义什么 url 在 2 之间打开 web-socket?我试过http:/apihttp://localhost:3050 但都没有成功

这是我的 nginx.conf 文件

upstream client {
    server client:3000;
}

upstream api {
    server api:8080;
}

server{

    listen 80;

    location / {
        proxy_pass http://client;
    }

    location /socket.io {
        proxy_pass http://api;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }

    location /api{
        rewrite /api/(.*) /$1 break;
        proxy_pass http://api;
    }
}

这是我的 docker compose

version: "3"
services:
  nginx:
    restart: always
    image: coco/nginx
    build:
      dockerfile: Dockerfile.dev
      context: ./nginx
    ports:
      - "3050:80"
  api:
    image: coco/server
    build:
      dockerfile: Dockerfile.dev
      context: ./server
    volumes:
      - /app/node_modules
      - ./server:/app
  client:
    image: coco/client
    build:
      dockerfile: Dockerfile.dev
      context: ./client
    volumes:
      - /app/node_modules
      - ./client:/app

关键问题在于反应容器,它需要使用这行代码设置 websocket 本身 const socket = socketIOClient("http:/api");,当它在本地主机上时它工作正常,现在当我开始docker-compose,它失败了。但是服务器能够接收到 axios 调用等,它只是 web-socket 不能从客户端建立

在我的 app.js 文件中我有这个

// configuring the port which is from config folder
let server = app.listen(config.port, function (err) {
    if (err) throw err;
    console.log("Server started on port " + config.port);
});

const io = require('socket.io').listen(server)
require('./routes/routes')(app, io)

在我的反应组件中,我有一个按钮,按下它时会执行以下逻辑

  const socket = socketIOClient("http://api");
    socket.on("connect", () => {
      console.log("Socket Connected");
      socket.on("tweets", data => {
       console.log(data)
      });
    });

但它不显示任何东西,也没有连接到任何东西

更新:

有一次它在没有太大变化的情况下工作,然后就死机了,我添加了几行代码来尝试调试它

 socket.on("error", function(err) {
        console.log("Socket.IO Error");
        console.log(err); // this is changed from your code in last comment
      });

这就是我发现的

Socket.IO Error
 Invalid namespace

【问题讨论】:

    标签: reactjs express docker nginx socket.io


    【解决方案1】:

    如果有人再次遇到这个问题,这里是解决方案

    1) 在socket.io实例中指定生产路径

    const socket = socketIOClient({ path: "/socket.io" });
    

    2) nginx内部,需要配置路由

    location /socket.io {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://api/socket.io/;
    }
    

    注意:位置与上一步中 socketIOClient 中指定的路径相同。然后,proxy_pass: 使用 /socket.io 引用服务器本身

    希望对某人有所帮助

    【讨论】:

      猜你喜欢
      • 2020-12-12
      • 2020-08-02
      • 2019-07-17
      • 2020-05-31
      • 1970-01-01
      • 1970-01-01
      • 2018-02-25
      • 2020-08-17
      • 2016-10-06
      相关资源
      最近更新 更多