Skip to content

Commit 1c4fe33

Browse files
committed
refactor!: WS client disconnection may not emit a disconnect event
The `disconnect` event is defined in the Integration-API and may not be used to signal a WebSocket disconnection. New events have been introduced to listen to WS connections and disconnections and a new `client_count` property to get the number of clients.
1 parent 098f4fb commit 1c4fe33

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

ucapi/api.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,24 +162,35 @@ async def _handle_ws(self, websocket) -> None:
162162
# authenticate on connection
163163
await self._authenticate(websocket, True)
164164

165+
self._events.emit(uc.Events.CLIENT_CONNECTED)
166+
165167
async for message in websocket:
166168
# process message
167169
await self._process_ws_message(websocket, message)
168170

169171
except ConnectionClosedOK:
170-
_LOG.info("WS: Connection closed")
172+
_LOG.info("[%s] WS: Connection closed", websocket.remote_address)
171173

172174
except websockets.exceptions.ConnectionClosedError as e:
173175
# no idea why they made code & reason deprecated...
174-
_LOG.info("WS: Connection closed with error %d: %s", e.code, e.reason)
176+
_LOG.info(
177+
"[%s] WS: Connection closed with error %d: %s",
178+
websocket.remote_address,
179+
e.code,
180+
e.reason,
181+
)
175182

176183
except websockets.exceptions.WebSocketException as e:
177-
_LOG.error("WS: Connection closed due to processing error: %s", e)
184+
_LOG.error(
185+
"[%s] WS: Connection closed due to processing error: %s",
186+
websocket.remote_address,
187+
e,
188+
)
178189

179190
finally:
180191
self._clients.remove(websocket)
181-
_LOG.info("WS: Client removed")
182-
self._events.emit(uc.Events.DISCONNECT)
192+
_LOG.info("[%s] WS: Client removed", websocket.remote_address)
193+
self._events.emit(uc.Events.CLIENT_DISCONNECTED)
183194

184195
async def _send_ok_result(
185196
self, websocket, req_id: int, msg_data: dict[str, Any] | list | None = None

ucapi/api_definitions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,23 @@ class WsMsgEvents(str, Enum):
8282
class Events(str, Enum):
8383
"""Internal library events."""
8484

85+
CLIENT_CONNECTED = "client_connected"
86+
"""WebSocket client connected."""
87+
CLIENT_DISCONNECTED = "client_disconnected"
88+
"""WebSocket client disconnected."""
8589
ENTITY_ATTRIBUTES_UPDATED = "entity_attributes_updated"
8690
SUBSCRIBE_ENTITIES = "subscribe_entities"
91+
"""Integration API `subscribe_events` message."""
8792
UNSUBSCRIBE_ENTITIES = "unsubscribe_entities"
93+
"""Integration API `unsubscribe_events` message."""
8894
CONNECT = "connect"
95+
"""Integration-API `connect` event message."""
8996
DISCONNECT = "disconnect"
97+
"""Integration-API `disconnect` event message."""
9098
ENTER_STANDBY = "enter_standby"
99+
"""Integration-API `enter_standby` event message."""
91100
EXIT_STANDBY = "exit_standby"
101+
"""Integration-API `exit_standby` event message."""
92102

93103

94104
# Does EventCategory need to be public?

0 commit comments

Comments
 (0)