From 9df52a0a89b3ac67f99637af19c11450788da89b Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Fri, 25 Mar 2022 13:26:26 +1100 Subject: [PATCH] implement new approach for call reconnection --- .../Calls/Call Management/SessionCall.swift | 23 ++++++++++++++++++- SessionMessagingKit/Calls/WebRTCSession.swift | 15 ++++-------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/Session/Calls/Call Management/SessionCall.swift b/Session/Calls/Call Management/SessionCall.swift index 71309a16e..9d3e3b94b 100644 --- a/Session/Calls/Call Management/SessionCall.swift +++ b/Session/Calls/Call Management/SessionCall.swift @@ -149,6 +149,8 @@ public final class SessionCall: NSObject, WebRTCSessionDelegate { return Date().timeIntervalSince(connectedDate) } + var reconnectTimer: Timer? = nil + // MARK: Initialization init(for sessionID: String, uuid: String, mode: Mode, outgoing: Bool = false) { self.sessionID = sessionID @@ -205,6 +207,7 @@ public final class SessionCall: NSObject, WebRTCSessionDelegate { Storage.shared.write { transaction in self?.webRTCSession.sendOffer(to: self!.sessionID, using: transaction as! YapDatabaseReadWriteTransaction).retainUntilComplete() } + self?.setupTimeoutTimer() } }) } @@ -307,9 +310,27 @@ public final class SessionCall: NSObject, WebRTCSessionDelegate { } } + public func reconnectIfNeeded() { + guard isOutgoing else { return } + tryToReconnect() + } + + private func tryToReconnect() { + reconnectTimer?.invalidate() + if SSKEnvironment.shared.reachabilityManager.isReachable { + Storage.write { transaction in + self.webRTCSession.sendOffer(to: self.sessionID, using: transaction, isRestartingICEConnection: true).retainUntilComplete() + } + } else { + reconnectTimer = Timer.scheduledTimerOnMainThread(withTimeInterval: 5, repeats: false) { _ in + self.tryToReconnect() + } + } + } + // MARK: Timeout public func setupTimeoutTimer() { - timeOutTimer = Timer.scheduledTimer(withTimeInterval: 30, repeats: false) { _ in + timeOutTimer = Timer.scheduledTimerOnMainThread(withTimeInterval: 30, repeats: false) { _ in self.didTimeout = true AppEnvironment.shared.callManager.endCall(self) { error in self.timeOutTimer = nil diff --git a/SessionMessagingKit/Calls/WebRTCSession.swift b/SessionMessagingKit/Calls/WebRTCSession.swift index aa5b0239e..190e0061d 100644 --- a/SessionMessagingKit/Calls/WebRTCSession.swift +++ b/SessionMessagingKit/Calls/WebRTCSession.swift @@ -8,6 +8,7 @@ public protocol WebRTCSessionDelegate : AnyObject { func isRemoteVideoDidChange(isEnabled: Bool) func dataChannelDidOpen() func didReceiveHangUpSignal() + func reconnectIfNeeded() } /// See https://webrtc.org/getting-started/overview for more information. @@ -103,16 +104,6 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate { dataChannel.delegate = self self.dataChannel = dataChannel } - - // Network reachability - NotificationCenter.default.addObserver(forName: .reachabilityChanged, object: nil, queue: nil) { _ in - print("[Calls] Reachability did change.") - if self.peerConnection.signalingState == .stable { - Storage.write { transaction in - self.sendOffer(to: self.contactSessionID, using: transaction, isRestartingICEConnection: true).retainUntilComplete() - } - } - } } // MARK: Signaling @@ -271,6 +262,10 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate { print("[Calls] ICE connection state changed to: \(state).") if state == .connected { delegate?.webRTCIsConnected() + } else if state == .disconnected { + if self.peerConnection.signalingState == .stable { + delegate?.reconnectIfNeeded() + } } }