Reactjs 与react和express(nginx、docker)建立web套接字通信

Reactjs 与react和express(nginx、docker)建立web套接字通信,reactjs,express,docker,nginx,socket.io,Reactjs,Express,Docker,Nginx,Socket.io,尝试设置websocket连接,当我在本地主机环境中时效果很好,但是一旦我设置了docker环境,客户端(react)就很难与express建立web套接字通信。我应该定义什么url使web套接字在2之间打开?我尝试了http:/api或http://localhost:3050但没有一个成功 这是我的nginx.conf文件 upstream client { server client:3000; } upstream api { server api:8080; } s

尝试设置websocket连接,当我在本地主机环境中时效果很好,但是一旦我设置了docker环境,客户端(react)就很难与express建立web套接字通信。我应该定义什么url使web套接字在2之间打开?我尝试了
http:/api
http://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;
    }
}
这是我的码头工人写的

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
关键问题在于react容器中,它需要使用以下代码行设置websocket本身:const socket=socketIOClient(“http:/api”);,当它在localhost上运行时,它工作得很好,而现在当我启动docker compose时,它失败了。然而,服务器能够接收axios调用等,只是无法从客户端建立web套接字

在我的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)
在我的react组件中,我有一个按钮,当按下时,它执行以下逻辑

  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

如果有人再次面临这个问题,下面是解决方案

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引用服务器本身


希望它能帮助别人

它有帮助,谢谢