@@ -488,25 +488,34 @@ public class StreamVideo: ObservableObject, @unchecked Sendable {
488488 } else {
489489 throw ClientError . Unknown ( )
490490 }
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- }
502491
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 ( )
510519 }
511520 }
512521
0 commit comments