FastAPI WebSocket
Use WebSocket parameter type for websocket endpoints.
1
2
@app.websocket('/ws')
async def websocket_endpoint(socket: WebSocket): ...
Accept Connection
At the very first you need to accept the connection.
1
await socket.accept()
Send/Receive API
1
2
3
4
5
6
data_json = await socket.receive_json()
data_text = await socket.receive_text()
data_bytes = await socket.receive_bytes()
await socket.send_json(data_json)
await socket.send_text(data_text)
await socket.send_bytes(data_bytes)
Data Frame
When using json format, you can choose which data frame to contain data with mode parameter.
Either text or binary is accepted, and default is text.
1
2
data_binary_json = socket.receive_json(mode='binary')
socket.send_json(data, mode='binary')
Iterators
Most common lifetime of websocket is a loop of receive -> send.
This is easily done by receive async iterators.
These iterators will exit when WebSocketDisconnected is raised.
1
2
3
async for data_text in socket.iter_text(): ...
async for data_json in socket.iter_json(): ...
async for data_bytes in socket.iter_bytes(): ...
Close Connection
Server can also close the connection.
1
await socket.close()
What’s Happening Underneath?
WebSocket type internally manages client and application state based on protocol,
which are CONNECTING, CONNECTED or DISCONNECTED.
Initially both client and application state are CONNECTING.
Client and application communicates over connection via sending and receiving socket Messages.
To initiate the connection, client is expected to send connect type message,
and then application is expected to respond with accept type message to accept or close type to refuse.
To close the connection properly, client is expected to send disconnect type message (client side disconnect),
or server is expected to send close type message (server side close).
However, keep in mind that the connection could be broken without closing handshake,
for example, when disconnected to network, server tries to send close message but raises IOError.
WebSocket provides low-level send and receive method that properly manages the states based on protocol.
When unexpected message is received or about to be sent, the socket will raise RuntimeError.
- On client state
CONNECTING, expects to receiveconnectmessageconnectmessage transforms client state toCONNECTED
- On client state
CONNECTED, expects to receivereceiveordisconnectmessagereceivemessage is normal message from clientdisconnectmessage transforms client state toDISCONNECTED
- On app state
CONNECTING, expects to sendacceptorclosemessageacceptmessage transforms app state toCONNECTEDclosemessage transforms app state toDISCONNECTED
- On app state
CONNECTED, expects to sendsendorclosemessagesendmessage is normal message from appclosemessage transforms app state toDISCONNECTED- I/O error transforms app state
DISCONNECTEDand raisesWebSocketDisconnect
All other APIs are implemented using send and receive.
acceptmethod waits forconnectmessage if client state isCONNECTING(receive()), then sendacceptmessage (send()).closemethod sendsclosemessage (send()).- All
receive_text,receive_json,receive_bytesexpect the app state to beCONNECTEDbeforereceive(), and raiseWebSocketDisconnectondisconnectmessage.receive_jsonadditionally validates the mode (textorbinary) beforereceive(), thenjson.loads()the data.receive_textcasts data tostr.receive_bytescasts data tobytes.
- All
iter_text,iter_json,iter_byteswrap their corresponding methods:1 2 3 4 5
try: while True: yield await self.receive_something() except WebSocketDisconnect: pass
- All
send_text,send_json,send_bytesattach the proper message type and callsend().send_jsonadditionally validates the mode andjson.dumps()the data.