nginx 在Docker compose网络中使用JS WebSocket

ig9co6j1  于 2023-04-29  发布在  Nginx
关注(0)|答案(1)|浏览(135)

我目前正在开发一个双向API,使用Python FastAPI作为后端,ReactJS作为前端。由于API调用应该是可扩展的,我想创建多个副本,可以通过也在Docker中运行的Nginx服务器访问。以下是我的docker compose文件:

version: "3.9"
services:

  api:
    build:
      context: api
    ports:
      - 8000

  load_balance:
    image: nginx:latest
    volumes:
      - ./dimer_api/nginx.conf:/etc/nginx/nginx.conf:rw
    depends_on:
      - api
    ports:
      - 8000:8000

  gui:
    build:
      context: gui
    ports:
      - 80:80
    depends_on:
      - load_balance

FastAPI代码如下所示:

websockets = []

@router.websocket("/api/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()

    try:
        while True:
            message = await websocket.receive_text()

            data = {"status": "ok", "type": "message", "message": message}

            await websocket.send_text(json.dumps(data))

    except WebSocketDisconnect:
        websockets.remove(message)

def create_app(debug: bool = False) -> FastAPI:
    app = FastAPI(debug=debug)

    app.include_router(router)

    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )

    return app

这里可以看到我的ReactJS脚本的UseEffect,它试图建立一个WebSocket连接。

useEffect(() => {
  const socket = new WebSocket("ws://localhost:8000/api/ws"); // ERROR

  socket.onopen = () => {
    console.log("WebSocket connection opened");
  };

  socket.onmessage = (event) => {
    const newData = JSON.parse(event.data);
    setData(newData);
  };

  return () => {
    socket.close();
  };
}, []);

为了提供所有信息,这里是API的配置文件:

events {
    worker_connections 1024;
}

http {
    server {
        listen 8000;

        location / {
            proxy_pass http://api:8000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }
}

ReactJS应用的.conf文件也运行在Nginx服务器上:

server {

  listen 80;

  location /api {
    proxy_pass http://load_balance:8000;
  }

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

  error_page   500 502 503 504  /50x.html;

  location = /50x.html {
    root   /usr/share/nginx/html;
  }

}

然而,我面临着在前端和后端之间建立WebSocket连接的问题。重要的部分是以下内容,我不知道该正确连接到什么:

const socket = new WebSocket("ws://localhost:8000/api/ws");

如何从GUI使用/api代理连接到FastAPI的WebSocket?或者我如何建立这种联系?

gmol1639

gmol16391#

使用load_balance代替localhost

const socket = new WebSocket("ws://load_balance:8000/api/ws");

你也可以使用postman进行WebSocket测试。

相关问题