Web 套接字可与本地 nginx 和 npm run dev 配合使用,但不适用于 docker compose

问题描述 投票:0回答:1

我有一个 React 前端和 NodeJS 后端,使用 nginx 提供服务和负载平衡。当我在本地运行 nginx 和 npm run dev 时,我的设置有效,但当我使用 docker compose 通过 docker 容器运行它时,Web 套接字无法连接。 在控制台中:

websocket.js:43 WebSocket connection to 'ws://localhost/socket.io/?userId=6500d7f273ec607346da303c&EIO=4&transport=websocket' failed:

我很茫然,我已经尝试了所有能找到的方法。这是我的设置。

docker-compose.yml

services:
  ws1:
    image: bark-mate-be
    environment:
      - APPID=1111
      - APPPORT=8081
    networks:
      - loadbalancing
    ports:
      - "8081:8080"
  ws2:
    image: bark-mate-be
    environment:
      - APPID=2222
      - APPPORT=8082
    ports:
      - "8082:8080"
    networks:
      - loadbalancing
  ws3:
    image: bark-mate-be
    environment:
      - APPID=3333
      - APPPORT=8083
    ports:
      - "8083:8080"
    networks:
      - loadbalancing
  barkmatefrontend:
    image: bark-mate-fe
    ports:
      - "3000:80"
    networks:
      - loadbalancing
    depends_on:
      - db
      - ws1
      - ws2
      - ws3
  db:
    volumes:
      - barkMate_db:/data/db
    image: mongo:latest
    ports:
      - "27017:27017"
volumes:
  barkMate_db:
networks:
  loadbalancing:

nginx.conf

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


upstream loadbalancer {
    # ip_hash;
    hash $remote_addr consistent;
    server ws1:8081;
    server ws2:8082;
}


server {
        listen 80;
        listen [::]:80;
        server_name localhost;

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

        location /api/ {
            proxy_pass http://loadbalancer;
            proxy_buffering on;  
        }

         location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;        
        }

}

socketio.js

import { io } from "socket.io-client";
const user = JSON.parse(localStorage.getItem("user"));

export let socket = io("http://localhost:80", {
  path: "/socket.io/",
  auth: { token: "token" },
  query: { userId: user ? JSON.parse(localStorage.getItem("user"))._id : "" },
  autoConnect: false,
  transports: ["websocket"],
  withCredentials: true,
});

socket.onAnyOutgoing((e, m) => {
   console.log("any out going", e, m);
});

socket.on("connect", () => {
   console.log("socket has connected");
  socket.emit("message", {
    type: "test",
    content: {
      msg: "test message",
      userId: JSON.parse(localStorage.getItem("user"))._id,
    },
  });
});

socket.on("message", (msg) => {
   console.log("client recieved the message", msg);
});

socket.io.on("reconnect", (attempt) => {
   console.log("socket reconnection success");
});

Dockerfile //客户端

FROM node:current-alpine as build
WORKDIR /app
COPY package*.json /app/
RUN npm install
RUN npm ci --production
COPY . .
RUN npm run build

FROM nginx:stable
COPY --from=build /app/build/ /usr/share/nginx/html
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
docker nginx websocket socket.io
1个回答
0
投票

我终于通过在套接字初始化中省略 url 来让它工作了,如下所示:

socketio.js

export let socket = io({
  path: "/socket.io/",
  auth: { token: "token" },
  query: { userId: user ? JSON.parse(localStorage.getItem("user"))._id : "" },
  autoConnect: false,
  transports: ["websocket"],
  withCredentials: true,
});

截至目前,我不确定为什么我不能像开发中那样点击 url,即将其指向 nginx 服务器,任何见解都将不胜感激,谢谢。

© www.soinside.com 2019 - 2024. All rights reserved.