首页 > 解决方案 > Nginx websocket已连接但客户端无法从api获取消息

问题描述

我用 nginx 部署 fastapi websocket。它似乎已连接(来自客户端的 websocket.readyState 为 1,客户端可以发送消息)但客户端无法从 API 获取消息。

这是我的 nginx websocket 配置

    location /ws {
        proxy_pass http://ta-solution:8001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade "websocket";
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_buffering off;
        proxy_connect_timeout 1d;
        proxy_send_timeout 1d;
        proxy_read_timeout 1d;
    }

和 nginx 得到了类似的错误

[2021-09-16 10:12:23 +0900] [9] [INFO] ('175.209.134.8', 0) - "WebSocket /ws/index" [accepted]
[2021-09-16 10:13:03 +0900] [9] [ERROR] Exception in ASGI application
Traceback (most recent call last):
  File "/app/main.py", line 98, in index_websocket_endpoint
    data = await websocket.receive_text()
  File "/usr/local/lib/python3.7/site-packages/starlette/websockets.py", line 83, in receive_text
    assert self.application_state == WebSocketState.CONNECTED
AssertionError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 203, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
  File "/usr/local/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/site-packages/fastapi/applications.py", line 208, in __call__
    await super().__call__(scope, receive, send)
  File "/usr/local/lib/python3.7/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/usr/local/lib/python3.7/site-packages/starlette/middleware/errors.py", line 146, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/site-packages/starlette/middleware/cors.py", line 70, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/site-packages/starlette/exceptions.py", line 58, in __call__
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/site-packages/starlette/routing.py", line 580, in __call__
    await route.handle(scope, receive, send)
  File "/usr/local/lib/python3.7/site-packages/starlette/routing.py", line 297, in handle
    await self.app(scope, receive, send)
  File "/usr/local/lib/python3.7/site-packages/starlette/routing.py", line 68, in app
    await func(session)
  File "/usr/local/lib/python3.7/site-packages/fastapi/routing.py", line 273, in app
    await dependant.call(**values)
  File "/app/main.py", line 110, in index_websocket_endpoint
    await websocket.close()
  File "/usr/local/lib/python3.7/site-packages/starlette/websockets.py", line 142, in close
    await self.send({"type": "websocket.close", "code": code})
  File "/usr/local/lib/python3.7/site-packages/starlette/websockets.py", line 70, in send
    raise RuntimeError('Cannot call "send" once a close message has been sent.')
RuntimeError: Cannot call "send" once a close message has been sent.

我确定它来自 nginx,因为它适用于本地(只有独角兽,而不是 nginx)。

有什么建议吗?

标签: pythonreactjsnginxwebsocketfastapi

解决方案


推荐阅读