0

Not able to understand how the ping pong is handled for python websockets package. The following is a simple fastapi websocket server and a python client. I expect keepalive timeout error but that does not happen.

FastAPI server:

from fastapi import FastAPI, WebSocket
import asyncio


app = FastAPI()
@app.get("/")
async def get():
    return "Hello" 

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    data = await websocket.receive_text() 
    
    await websocket.send_text('test')
    await asyncio.sleep(45)
    
    await websocket.send_text(f"Stop")

Python Client

import websockets
import asyncio

async def communicate():
    async with websockets.connect("ws://localhost:8000/ws",
                                  ping_timeout=2, 
                                  ) as websocket:
        
        await websocket.send("Tom")
        while True:
            response = await websocket.recv()
            print(response)
            if response == "Stop":  
                break
            

if __name__ =="__main__":
    
    asyncio.get_event_loop().run_until_complete(communicate())

Expected Outcome

test -- < Keepalive timeout error >

Actual Outcome:

test

Stop

--> Could someone explain how the ping-pong mechanism works and does the number of CPU cores or available uvicorn workers affect ping-pong mechanism.

Thank you in advance.

Baenka
  • 243
  • 3
  • 15
  • Are you expecting the sleep to cause the websocket to stop communicating? I dont know the implementation, but perhaps it is happening on a separate thread. Otherwise you would have to be careful not to place long running code in your server side handler. – Jeppe Feb 03 '22 at 11:29
  • @Jeppe, I am expecting the client timeout in the above scenario. This is a simplified version of another code of mine where there is a long running code inside the server side handler. The code at the server side could take up to 30s. In the actual implementation, I often get keepalive ping timeout error on the clientside side. So I am expecting a similar timeout in the above scenario. – Baenka Feb 04 '22 at 06:16
  • 1
    Is your long running code async and being awaited? Replace `await asyncio.sleep(45)` with `time.sleep(45)` and you get the error. – Jeppe Feb 04 '22 at 08:55
  • 1
    Changing `await asyncio.sleep(45)` with `time.sleep(45)` throws the keepalive timeout error. From this finding I understand that it takes about ping_interval + ping_timout duration for websocket to timeout. If the code is non-blocking like await async.sleep(), the timeout will never happen as is a possibility for ping pong mechanism to happen. – Baenka Feb 07 '22 at 04:06

0 Answers0