From e3ef3598d71e70f69b6d7ecdab4e1c5fbbac4740 Mon Sep 17 00:00:00 2001 From: isaacakakpo1 Date: Fri, 3 Nov 2023 12:50:51 +0000 Subject: [PATCH] Re-Establish Connection Feature --- TelnyxRTC/Telnyx/Models/TxConfig.swift | 6 +++- TelnyxRTC/Telnyx/TxClient.swift | 18 ++++++++-- TelnyxRTCTests/TelnyxRTCTests.swift | 49 ++++++++++++++++++++++++++ TelnyxRTCTests/WebRTC/CallTests.swift | 23 ++++++++++++ 4 files changed, 93 insertions(+), 3 deletions(-) diff --git a/TelnyxRTC/Telnyx/Models/TxConfig.swift b/TelnyxRTC/Telnyx/Models/TxConfig.swift index 668ee9b3..8013edfb 100644 --- a/TelnyxRTC/Telnyx/Models/TxConfig.swift +++ b/TelnyxRTC/Telnyx/Models/TxConfig.swift @@ -19,6 +19,7 @@ public struct TxConfig { public internal(set) var ringBackTone: String? public internal(set) var ringtone: String? + public internal(set) var reconnectClient: Bool = false // MARK: - Initializers @@ -34,7 +35,9 @@ public struct TxConfig { pushDeviceToken: String? = nil, ringtone: String? = nil, ringBackTone: String? = nil, - logLevel: LogLevel = .none) { + logLevel: LogLevel = .none, + reconnectClient:Bool = false + ) { self.sipUser = sipUser self.password = password if let pushToken = pushDeviceToken { @@ -43,6 +46,7 @@ public struct TxConfig { } self.ringBackTone = ringBackTone self.ringtone = ringtone + self.reconnectClient = reconnectClient Logger.log.verboseLevel = logLevel } diff --git a/TelnyxRTC/Telnyx/TxClient.swift b/TelnyxRTC/Telnyx/TxClient.swift index ade0ed6d..1ce6a374 100644 --- a/TelnyxRTC/Telnyx/TxClient.swift +++ b/TelnyxRTC/Telnyx/TxClient.swift @@ -125,7 +125,8 @@ public class TxClient { // MARK: - Properties private static let DEFAULT_REGISTER_INTERVAL = 3.0 // In seconds private static let MAX_REGISTER_RETRY = 3 // Number of retry - + //re_connect buffer in secondds + private static let RECONNECT_BUFFER = 2.0 /// Keeps track of all the created calls by theirs UUIDs public internal(set) var calls: [UUID: Call] = [UUID: Call]() /// Subscribe to TxClient delegate to receive Telnyx SDK events @@ -146,6 +147,7 @@ public class TxClient { private var pendingAnswerHeaders = [String:String]() private var speakerOn:Bool = false + func isSpeakerEnabled() -> Bool { return speakerOn } @@ -593,7 +595,7 @@ extension TxClient: CallProtocol { Listen for wss socket events */ extension TxClient : SocketDelegate { - + func onSocketConnected() { Logger.log.i(message: "TxClient:: SocketDelegate onSocketConnected()") self.delegate?.onSocketConnected() @@ -627,6 +629,18 @@ extension TxClient : SocketDelegate { func onSocketError(error: Error) { Logger.log.i(message: "TxClient:: SocketDelegate onSocketError()") self.delegate?.onClientError(error: error) + if let txConfig = self.txConfig { + if(txConfig.reconnectClient){ + DispatchQueue.main.asyncAfter(deadline: .now() + TxClient.RECONNECT_BUFFER) { + do { + try self.connect(txConfig: txConfig,serverConfiguration: self.serverConfiguration) + }catch let error { + Logger.log.e(message: error.localizedDescription) + } + } + } + } + } /** diff --git a/TelnyxRTCTests/TelnyxRTCTests.swift b/TelnyxRTCTests/TelnyxRTCTests.swift index 4edce7d4..ea0e33a3 100644 --- a/TelnyxRTCTests/TelnyxRTCTests.swift +++ b/TelnyxRTCTests/TelnyxRTCTests.swift @@ -149,6 +149,55 @@ class TelnyxRTCTests: XCTestCase { wait(for: [expectation], timeout: 10) } + /** + Test resetablish connection + */ + func testReconnectUser(){ + + class TestDelegate: RTCTestDelegate { + //wait for client error to be called + override func onClientError(error: Error) { + self.expectation.fulfill() + } + + // We are going to wait the session to be updated + override func onSessionUpdated(sessionId: String) { + self.expectation.fulfill() + } + } + + class TestError : Error { + var reason = "" + init(reason:String){ + self.reason = reason + } + } + + let errorExpectation = XCTestExpectation() + let telnyxClient = TxClient() + let delegate = TestDelegate(expectation: errorExpectation) + + let txConfig = TxConfig(sipUser: TestConstants.sipUser, + password: TestConstants.sipPassword,reconnectClient: true) + + telnyxClient.delegate = delegate + try! telnyxClient.connect(txConfig: txConfig) + telnyxClient.onSocketError(error:TestError(reason: "Socket Error")) + + //Error rcpection should be fulfiled + wait(for: [errorExpectation], timeout: 10) + + let connectExpectation = XCTestExpectation() + let connectDelegate = TestDelegate(expectation: connectExpectation) + telnyxClient.delegate = connectDelegate + + //The client should be connected without calling connect again. + wait(for: [connectExpectation], timeout: 10) + + let sessionId = telnyxClient.getSessionId() + XCTAssertFalse(sessionId.isEmpty) // We should get a session ID + } + /** Test login with valid credentials - Connects to wss diff --git a/TelnyxRTCTests/WebRTC/CallTests.swift b/TelnyxRTCTests/WebRTC/CallTests.swift index f3bd47d5..6e1c62e9 100644 --- a/TelnyxRTCTests/WebRTC/CallTests.swift +++ b/TelnyxRTCTests/WebRTC/CallTests.swift @@ -47,6 +47,29 @@ class CallTests: XCTestCase { self.call?.newCall(callerName: "callerName", callerNumber: "callerNumber", destinationNumber: "destinationNumber") waitForExpectations(timeout: 10) } + + /** + Test that the invite message is sent through the socket. + - Wait socket connection to be completed. + - Starts the call process by creating an offer + - Once the ICE candidates negotiation finishes, we send an invite through the socket. + - Wait for a server response onMessageReceived. + - NOTE: Due that we are not sending a valid sessionID we are going to get an "Authentication error" from the server. + */ + func testCallWithCustomHeaders() { + //Wait for socket connection + expectation = expectation(description: "socket") + waitForExpectations(timeout: 10) + + //Wait to send invite message. + expectation = expectation(description: "newCall") + self.call?.newCall(callerName: "callerName", callerNumber: "callerNumber", destinationNumber: "destinationNumber",customHeaders: ["X-test1":"ios-test1", + "X-test2":"ios-test2"]) + waitForExpectations(timeout: 10) + + let customHeaders = call?.inviteCustomHeaders + XCTAssertFalse(customHeaders?.isEmpty == true) // We should get a session ID + } } // MARK: - CallProtocol