Что происходит с существующими ожиданиями при вызове WebSocket.close - PullRequest
3 голосов
/ 09 мая 2020

Если я открою WebSocket Starlette / FastAPI, что произойдет с любыми сопрограммами, ожидающими в настоящее время получения данных от клиента, если я закрою 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 Ответ

1 голос
/ 19 мая 2020

Он вызывает 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" }')
...