Fix ws error

This commit is contained in:
Xin Wang
2026-02-09 15:53:21 +08:00
parent 8fd6daaed1
commit cb5c08d84d

View File

@@ -69,6 +69,13 @@ class SocketTransport(BaseTransport):
self.lock = asyncio.Lock() # Prevent frame interleaving self.lock = asyncio.Lock() # Prevent frame interleaving
self._closed = False self._closed = False
def _ws_disconnected(self) -> bool:
"""Best-effort check for websocket disconnection state."""
return (
self.ws.client_state == WebSocketState.DISCONNECTED
or self.ws.application_state == WebSocketState.DISCONNECTED
)
async def send_event(self, event: dict) -> None: async def send_event(self, event: dict) -> None:
""" """
Send a JSON event via WebSocket. Send a JSON event via WebSocket.
@@ -76,17 +83,27 @@ class SocketTransport(BaseTransport):
Args: Args:
event: Event data as dictionary event: Event data as dictionary
""" """
if self._closed: if self._closed or self._ws_disconnected():
logger.warning("Attempted to send event on closed transport") logger.warning("Attempted to send event on closed transport")
self._closed = True
return return
async with self.lock: async with self.lock:
try: try:
await self.ws.send_text(json.dumps(event)) await self.ws.send_text(json.dumps(event))
logger.debug(f"Sent event: {event.get('event', 'unknown')}") logger.debug(f"Sent event: {event.get('event', 'unknown')}")
except Exception as e: except RuntimeError as e:
logger.error(f"Error sending event: {e}")
self._closed = True self._closed = True
if self._ws_disconnected() or "close message has been sent" in str(e):
logger.debug(f"Skip sending event on closed websocket: {e!r}")
return
logger.error(f"Error sending event: {e!r}")
except Exception as e:
self._closed = True
if self._ws_disconnected():
logger.debug(f"Skip sending event on disconnected websocket: {e!r}")
return
logger.error(f"Error sending event: {e!r}")
async def send_audio(self, pcm_bytes: bytes) -> None: async def send_audio(self, pcm_bytes: bytes) -> None:
""" """
@@ -95,16 +112,26 @@ class SocketTransport(BaseTransport):
Args: Args:
pcm_bytes: PCM audio data (16-bit, mono, 16kHz) pcm_bytes: PCM audio data (16-bit, mono, 16kHz)
""" """
if self._closed: if self._closed or self._ws_disconnected():
logger.warning("Attempted to send audio on closed transport") logger.warning("Attempted to send audio on closed transport")
self._closed = True
return return
async with self.lock: async with self.lock:
try: try:
await self.ws.send_bytes(pcm_bytes) await self.ws.send_bytes(pcm_bytes)
except Exception as e: except RuntimeError as e:
logger.error(f"Error sending audio: {e}")
self._closed = True self._closed = True
if self._ws_disconnected() or "close message has been sent" in str(e):
logger.debug(f"Skip sending audio on closed websocket: {e!r}")
return
logger.error(f"Error sending audio: {e!r}")
except Exception as e:
self._closed = True
if self._ws_disconnected():
logger.debug(f"Skip sending audio on disconnected websocket: {e!r}")
return
logger.error(f"Error sending audio: {e!r}")
async def close(self) -> None: async def close(self) -> None:
"""Close the WebSocket connection.""" """Close the WebSocket connection."""
@@ -112,10 +139,7 @@ class SocketTransport(BaseTransport):
return return
self._closed = True self._closed = True
if ( if self._ws_disconnected():
self.ws.client_state == WebSocketState.DISCONNECTED
or self.ws.application_state == WebSocketState.DISCONNECTED
):
return return
try: try: