调用 WebSocket.close 时现有等待会发生啥
Posted
技术标签:
【中文标题】调用 WebSocket.close 时现有等待会发生啥【英文标题】:What happens to existing awaits when WebSocket.close is called调用 WebSocket.close 时现有等待会发生什么 【发布时间】:2020-08-24 13:24:32 【问题描述】:如果我打开 Starlette/FastAPI WebSocket,如果我从协程外部关闭 WebSocket,当前等待从客户端接收数据的协程会发生什么情况?对receive
的调用是否引发异常,或者协程是否因为永远不会收到任何东西而永远驻留在内存中?
from fastapi import FastAPI
from fastapi.websockets import WebSocket
app = FastAPI()
open_sockets =
@app.websocket('/connection/')
async def connection(websocket: WebSocket):
await websocket.accept()
id = await websocket.receive_json()['id']
open_sockets[id] = websocket
while True:
data = await websocket.receive_json()
@app.post('/kill/id/')
async def kill(id=str):
# What does this do to the above `await websocket.receive_json()`?
await open_sockets[id].close()
del open_sockets[id]
【问题讨论】:
【参考方案1】:它引发starlette.websockets.WebSocketDisconnect
,代码为 1006
File ".\websocket_close_test.py", line 27, in connection
data = await websocket.receive_json()
File "C:\Apps\Python38\lib\site-packages\starlette\websockets.py", line 98, in receive_json
self._raise_on_disconnect(message)
File "C:\Apps\Python38\lib\site-packages\starlette\websockets.py", line 80, in _raise_on_disconnect
raise WebSocketDisconnect(message["code"])
我确实注意到 .close() 调用被阻塞了一段时间。
这是我用来测试的代码,第二个ws.send
从未收到。
import time
import requests
import websocket
ws = websocket.WebSocket()
ws.connect("ws://localhost:8000/connection/")
print('Sending id 0')
ws.send(' "id": "0" ')
time.sleep(2)
print('Closing id 0')
requests.post('http://localhost:8000/kill/0/')
print('id 0 is closed')
time.sleep(2)
print('Trying to send data on closed connection')
ws.send(' "id": "10" ')
【讨论】:
以上是关于调用 WebSocket.close 时现有等待会发生啥的主要内容,如果未能解决你的问题,请参考以下文章
Python 服务器 - 处理 WebSocket.close()
预期的 ASGI 消息“websocket.accept”或“websocket.close”,但得到“http.response.start”