预期的 ASGI 消息“websocket.accept”或“websocket.close”,但得到“http.response.start”
Posted
技术标签:
【中文标题】预期的 ASGI 消息“websocket.accept”或“websocket.close”,但得到“http.response.start”【英文标题】:Expected ASGI message 'websocket.accept' or 'websocket.close', but got 'http.response.start' 【发布时间】:2021-03-02 10:39:12 【问题描述】:我想连接websockets
,但在启动时出现错误。
uvicorn app:app --reload --ws websockets
要求
操作系统:Linux Ubuntu 20.04 LTS
Python 3.8.6
浏览器:Chrome 88.0.4324.182
fastapi==0.63.0
python-engineio==4.0.0
python-socketio==5.0.4
小星星==0.13.6
uvicorn==0.13.3
网络套接字==8.1
app.py
from typing import Optional
import socketio
from fastapi import FastAPI, Query, WebSocket
sio = socketio.AsyncServer(
async_mode="asgi", cors_allowed_origins="*", logger=True, engineio_logger=True
)
app = FastAPI(debug=True)
app_socketio = socketio.ASGIApp(sio)
app.mount(path="/", app=app_socketio)
@app.websocket("/items/item_id/ws")
async def websocket_endpoint(
websocket: WebSocket,
item_id: str,
q: Optional[int] = None,
):
# pylint: disable=C0103,W0613
await websocket.accept()
while True:
data: str = await websocket.receive_text()
反应应用
const Index: React.FC = () =>
var ws = new WebSocket('ws://127.0.0.1:8000/items/1/ws')
追溯
Traceback (most recent call last):
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 157, in run_asgi
result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/fastapi/applications.py", line 199, in __call__
await super().__call__(scope, receive, send)
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/starlette/applications.py", line 111, in __call__
await self.middleware_stack(scope, receive, send)
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/starlette/middleware/errors.py", line 146, in __call__
await self.app(scope, receive, send)
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/starlette/exceptions.py", line 58, in __call__
await self.app(scope, receive, send)
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/starlette/routing.py", line 566, in __call__
await route.handle(scope, receive, send)
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/starlette/routing.py", line 376, in handle
await self.app(scope, receive, send)
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/engineio/async_drivers/asgi.py", line 65, in __call__
await self.not_found(receive, send)
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/engineio/async_drivers/asgi.py", line 110, in not_found
await send('type': 'http.response.start',
File "/home/m0nte-cr1st0/.virtualenvs/hypercube/lib/python3.8/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 209, in asgi_send
raise RuntimeError(msg % message_type)
RuntimeError: Expected ASGI message 'websocket.accept' or 'websocket.close', but got 'http.response.start'.
【问题讨论】:
【参考方案1】:const Index: React.FC = () =>
var ws = new WebSocket('ws://127.0.0.1:8000/items/1/ws')
将此函数设为异步并等待并重试
【讨论】:
以上是关于预期的 ASGI 消息“websocket.accept”或“websocket.close”,但得到“http.response.start”的主要内容,如果未能解决你的问题,请参考以下文章
Django 现在在 Heroku 中使用 ASGI + WSGI 的频道