44from logging import getLogger
55from typing import TYPE_CHECKING
66
7- from websockets .exceptions import ConnectionClosed , ConnectionClosedError , ConnectionClosedOK
7+ from websockets .exceptions import ConnectionClosed , ConnectionClosedOK
88from websockets .sync .client import ClientConnection , connect
99
1010
1111if TYPE_CHECKING :
1212 from collections .abc import Generator
1313 from typing import Any
1414
15- from typing_extensions import Self
15+ from typing_extensions import Self # noqa: UP035
1616
1717
1818logger = getLogger ("streamdeck.websocket" )
@@ -38,10 +38,14 @@ def send_event(self, data: dict[str, Any]) -> None:
3838 Args:
3939 data (dict[str, Any]): The event data to send.
4040 """
41+ if self ._client is None :
42+ msg = "WebSocket connection not established yet."
43+ raise ValueError (msg )
44+
4145 data_str = json .dumps (data )
4246 self ._client .send (message = data_str )
4347
44- def listen_forever (self ) -> Generator [str | bytes , Any , None ]:
48+ def listen (self ) -> Generator [str | bytes , Any , None ]:
4549 """Listen for messages from the WebSocket server indefinitely.
4650
4751 TODO: implement more concise error-handling.
@@ -55,20 +59,34 @@ def listen_forever(self) -> Generator[str | bytes, Any, None]:
5559 message : str | bytes = self ._client .recv ()
5660 yield message
5761
62+ except ConnectionClosedOK :
63+ logger .debug ("Connection was closed normally, stopping the client." )
64+
65+ except ConnectionClosed :
66+ logger .exception ("Connection was closed with an error." )
67+
5868 except Exception :
59- logger .exception ("Failed to receive messages from websocket server." )
69+ logger .exception ("Failed to receive messages from websocket server due to unexpected error." )
70+
71+ def start (self ) -> None :
72+ """Start the connection to the websocket server."""
73+ self ._client = connect (uri = f"ws://localhost:{ self ._port } " )
74+
75+ def stop (self ) -> None :
76+ """Close the WebSocket connection, if open."""
77+ if self ._client is not None :
78+ self ._client .close ()
6079
6180 def __enter__ (self ) -> Self :
6281 """Start the connection to the websocket server.
6382
6483 Returns:
6584 Self: The WebSocketClient instance after connecting to the WebSocket server.
6685 """
67- self ._client = connect ( uri = f"ws://localhost: { self . _port } " )
86+ self .start ( )
6887 return self
6988
7089 def __exit__ (self , * args , ** kwargs ) -> None :
7190 """Close the WebSocket connection, if open."""
72- if self ._client is not None :
73- self ._client .close ()
91+ self .stop ()
7492
0 commit comments