@@ -913,6 +913,25 @@ async def _force_flush(self) -> None:
913913 self ._pending_messages .clear ()
914914 self ._pending_bytes = 0
915915
916+ async def _ping (self ) -> None :
917+ """Send a PING to the server."""
918+ self ._pong_waker .clear ()
919+ logger .debug ("->> PING" )
920+ self ._pings_outstanding += 1
921+ self ._last_ping_sent = asyncio .get_running_loop ().time ()
922+ await self ._connection .write (encode_ping ())
923+
924+ async def rtt (self , timeout : float | None = None ) -> float :
925+ """Calculate the round trip time between the client and server in seconds."""
926+ if self ._status == ClientStatus .CLOSED :
927+ raise ConnectionError ("connection is closed" )
928+
929+ loop = asyncio .get_running_loop ()
930+ start = loop .time ()
931+ await self ._ping ()
932+ await asyncio .wait_for (self ._pong_waker .wait (), timeout = timeout )
933+ return loop .time () - start
934+
916935 async def flush (self , timeout : float | None = None ) -> None :
917936 """Flush pending messages with optional timeout."""
918937 if self ._status == ClientStatus .CLOSED :
@@ -922,11 +941,7 @@ async def flush(self, timeout: float | None = None) -> None:
922941 if self ._pending_messages :
923942 await self ._force_flush ()
924943
925- self ._pong_waker .clear ()
926- logger .debug ("->> PING" )
927- self ._pings_outstanding += 1
928- self ._last_ping_sent = asyncio .get_event_loop ().time ()
929- await self ._connection .write (encode_ping ())
944+ await self ._ping ()
930945 try :
931946 await asyncio .wait_for (self ._pong_waker .wait (), timeout = timeout )
932947 except asyncio .TimeoutError :
0 commit comments