@@ -94,16 +94,15 @@ def _create_client_state(self, client_id: Text) -> ClientState:
94
94
pipeline = self .pipeline_class (self .pipeline_config )
95
95
96
96
audio_source = src .WebSocketAudioSource (
97
- uri = f"{ self .uri } :{ client_id } " ,
98
- sample_rate = self .pipeline_config .sample_rate ,
97
+ uri = f"{ self .uri } :{ client_id } " , sample_rate = self .pipeline_config .sample_rate ,
99
98
)
100
99
101
100
inference = StreamingInference (
102
101
pipeline = pipeline ,
103
102
source = audio_source ,
104
103
# The following variables are fixed for a client
105
104
batch_size = 1 ,
106
- do_profile = False , # for minimal latency
105
+ do_profile = False , # for minimal latency
107
106
do_plot = False ,
108
107
show_progress = False ,
109
108
progress_bar = None ,
@@ -143,6 +142,11 @@ def _on_connect(self, client: Dict[Text, Any], server: WebsocketServer) -> None:
143
142
self .send (client_id , "READY" )
144
143
except Exception as e :
145
144
logger .error (f"Failed to initialize client { client_id } : { e } " )
145
+
146
+ # Send close notification to client
147
+ self .send (client_id , "CLOSE" )
148
+
149
+ # Close audio source and remove client
146
150
self .close (client_id )
147
151
148
152
def _on_disconnect (self , client : Dict [Text , Any ], server : WebsocketServer ) -> None :
@@ -157,6 +161,11 @@ def _on_disconnect(self, client: Dict[Text, Any], server: WebsocketServer) -> No
157
161
"""
158
162
client_id = client ["id" ]
159
163
logger .info (f"Client disconnected: { client_id } " )
164
+
165
+ # Send close notification to client
166
+ self .send (client_id , "CLOSE" )
167
+
168
+ # Close audio source and remove client
160
169
self .close (client_id )
161
170
162
171
def _on_message_received (
@@ -182,7 +191,13 @@ def _on_message_received(
182
191
self ._clients [client_id ].audio_source .process_message (message )
183
192
except (socket .error , ConnectionError ) as e :
184
193
logger .warning (f"Client { client_id } disconnected: { e } " )
194
+
195
+ # Send close notification to client
196
+ self .send (client_id , "CLOSE" )
197
+
198
+ # Close audio source and remove client
185
199
self .close (client_id )
200
+
186
201
except Exception as e :
187
202
logger .error (f"Error processing message from client { client_id } : { e } " )
188
203
# Don't close the connection for non-connection related errors
@@ -202,45 +217,14 @@ def send(self, client_id: Text, message: AnyStr) -> None:
202
217
return
203
218
204
219
client = next ((c for c in self .server .clients if c ["id" ] == client_id ), None )
205
-
206
220
if client is None :
207
221
return
208
222
209
223
try :
210
224
self .server .send_message (client , message )
211
- except (socket .error , ConnectionError ) as e :
212
- logger .warning (
213
- f"Client { client_id } disconnected while sending message: { e } "
214
- )
215
- self .close (client_id )
216
225
except Exception as e :
217
226
logger .error (f"Failed to send message to client { client_id } : { e } " )
218
227
219
- def run (self ) -> None :
220
- """Start the WebSocket server."""
221
- logger .info (f"Starting WebSocket server on { self .uri } " )
222
- max_retries = 3
223
- retry_count = 0
224
-
225
- while retry_count < max_retries :
226
- try :
227
- self .server .run_forever ()
228
- break # If server exits normally, break the retry loop
229
- except (socket .error , ConnectionError ) as e :
230
- logger .warning (f"WebSocket connection error: { e } " )
231
- retry_count += 1
232
- if retry_count < max_retries :
233
- logger .info (
234
- f"Attempting to restart server (attempt { retry_count + 1 } /{ max_retries } )"
235
- )
236
- else :
237
- logger .error ("Max retry attempts reached. Server shutting down." )
238
- except Exception as e :
239
- logger .error (f"Fatal server error: { e } " )
240
- break
241
- finally :
242
- self .close_all ()
243
-
244
228
def close (self , client_id : Text ) -> None :
245
229
"""Close a specific client's connection and cleanup resources.
246
230
@@ -261,22 +245,6 @@ def close(self, client_id: Text) -> None:
261
245
client_state .audio_source .close ()
262
246
del self ._clients [client_id ]
263
247
264
- # Try to send a close frame to the client
265
- client = next ((c for c in self .server .clients if c ["id" ] == client_id ), None )
266
-
267
- if client is None :
268
- return
269
-
270
- try :
271
- self .server .send_message (client , "CLOSE" )
272
- except (socket .error , ConnectionError ) as e :
273
- logger .warning (
274
- f"Client { client_id } disconnected while sending message: { e } "
275
- )
276
- self .close (client_id )
277
- except Exception as e :
278
- logger .error (f"Failed to send message to client { client_id } : { e } " )
279
-
280
248
logger .info (
281
249
f"Closed connection and cleaned up state for client: { client_id } "
282
250
)
@@ -290,9 +258,40 @@ def close_all(self) -> None:
290
258
logger .info ("Shutting down server..." )
291
259
try :
292
260
for client_id in self ._clients .keys ():
261
+ # Close audio source and remove client
293
262
self .close (client_id )
263
+
264
+ # Send close notification to client
265
+ self .send (client_id , "CLOSE" )
266
+
294
267
if self .server is not None :
295
268
self .server .shutdown_gracefully ()
269
+
296
270
logger .info ("Server shutdown complete" )
297
271
except Exception as e :
298
272
logger .error (f"Error during shutdown: { e } " )
273
+
274
+ def run (self ) -> None :
275
+ """Start the WebSocket server."""
276
+ logger .info (f"Starting WebSocket server on { self .uri } " )
277
+ max_retries = 3
278
+ retry_count = 0
279
+
280
+ while retry_count < max_retries :
281
+ try :
282
+ self .server .run_forever ()
283
+ break # If server exits normally, break the retry loop
284
+ except (socket .error , ConnectionError ) as e :
285
+ logger .warning (f"WebSocket connection error: { e } " )
286
+ retry_count += 1
287
+ if retry_count < max_retries :
288
+ logger .info (
289
+ f"Attempting to restart server (attempt { retry_count + 1 } /{ max_retries } )"
290
+ )
291
+ else :
292
+ logger .error ("Max retry attempts reached. Server shutting down." )
293
+ except Exception as e :
294
+ logger .error (f"Fatal server error: { e } " )
295
+ break
296
+ finally :
297
+ self .close_all ()
0 commit comments