@@ -488,25 +488,34 @@ public class StreamVideo: ObservableObject, @unchecked Sendable {
488
488
} else {
489
489
throw ClientError . Unknown ( )
490
490
}
491
- var connected = false
492
- var timeout = false
493
- let control = DefaultTimer . schedule ( timeInterval: 30 , queue: . sdk) {
494
- timeout = true
495
- }
496
- log. debug ( " Listening for WS connection " )
497
- webSocketClient? . onConnected = {
498
- control. cancel ( )
499
- connected = true
500
- log. debug ( " WS connected " )
501
- }
502
491
503
- while ( !connected && !timeout) {
504
- try await Task . sleep ( nanoseconds: 100_000 )
505
- }
506
-
507
- if timeout {
508
- log. debug ( " Timeout while waiting for WS connection opening " )
509
- throw ClientError . NetworkError ( )
492
+ log. debug ( " Listening for WS connection " )
493
+ var continuationHandler : ( ( ) -> Void ) ? = nil
494
+ try await withThrowingTaskGroup ( of: Void . self) { group in
495
+ group. addTask {
496
+ try await Task . sleep ( nanoseconds: 30 * 1_000_000_000 )
497
+ log. debug ( " Timeout while waiting for WS connection opening " )
498
+ continuationHandler = nil
499
+ throw ClientError . NetworkError ( )
500
+ }
501
+ group. addTask {
502
+ try await withCheckedThrowingContinuation { ( continuation: CheckedContinuation < Void , Error > ) in
503
+ continuationHandler = {
504
+ continuation. resume ( returning: ( ) )
505
+ }
506
+ webSocketClient? . onConnected = { [ weak self] in
507
+ self ? . log. debug ( " WS connected " )
508
+ // Only resume if the handler still exists
509
+ if let continuationHandler {
510
+ continuationHandler ( )
511
+ continuationHandler = nil
512
+ }
513
+ }
514
+ }
515
+ }
516
+ // race between “onConnected” and 30s timeout: whichever finishes first “wins”
517
+ try await group. next ( )
518
+ group. cancelAll ( )
510
519
}
511
520
}
512
521
0 commit comments