Handling reconnect scenarios properly when socket is hung

This commit is contained in:
Mark Schisler 2021-08-19 09:30:29 -05:00
parent d031afdbc4
commit ec4378ca49
No known key found for this signature in database
GPG Key ID: CBDBB5F8041C510E
6 changed files with 49 additions and 6 deletions

2
.gitignore vendored
View File

@ -50,3 +50,5 @@ Socket.IO-Test-Server/node_modules/*
.idea/ .idea/
docs/docsets/ docs/docsets/
docs/undocumented.json docs/undocumented.json
.swiftpm

View File

@ -150,6 +150,7 @@ open class SocketIOClient: NSObject, SocketIOClientSpec {
manager.handleQueue.asyncAfter(deadline: DispatchTime.now() + timeoutAfter) {[weak self] in manager.handleQueue.asyncAfter(deadline: DispatchTime.now() + timeoutAfter) {[weak self] in
guard let this = self, this.status == .connecting || this.status == .notConnected else { return } guard let this = self, this.status == .connecting || this.status == .notConnected else { return }
DefaultSocketLogger.Logger.log("Timeout: Socket not connected, so setting to disconnected", type: this.logType)
this.status = .disconnected this.status = .disconnected
this.leaveNamespace() this.leaveNamespace()

View File

@ -132,7 +132,7 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat
private(set) var reconnectAttempts = -1 private(set) var reconnectAttempts = -1
private var _config: SocketIOClientConfiguration private var _config: SocketIOClientConfiguration
private var currentReconnectAttempt = 0 internal var currentReconnectAttempt = 0
private var reconnecting = false private var reconnecting = false
// MARK: Initializers // MARK: Initializers
@ -186,9 +186,8 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat
/// ///
/// Override if you wish to attach a custom `SocketEngineSpec`. /// Override if you wish to attach a custom `SocketEngineSpec`.
open func connect() { open func connect() {
guard !status.active else { if status == .connected || (status == .connecting && currentReconnectAttempt == 0) {
DefaultSocketLogger.Logger.log("Tried connecting an already active socket", type: SocketManager.logType) DefaultSocketLogger.Logger.log("Tried connecting an already active socket", type: SocketManager.logType)
return return
} }

View File

@ -28,7 +28,6 @@ class SocketAckManagerTest : XCTestCase {
func testManagerTimeoutAck() { func testManagerTimeoutAck() {
let callbackExpection = expectation(description: "Manager should timeout ack with noAck status") let callbackExpection = expectation(description: "Manager should timeout ack with noAck status")
let itemsArray = ["Hi", "ho"]
func callback(_ items: [Any]) { func callback(_ items: [Any]) {
XCTAssertEqual(items.count, 1, "Timed out ack should have one value") XCTAssertEqual(items.count, 1, "Timed out ack should have one value")

View File

@ -60,6 +60,44 @@ class SocketMangerTest : XCTestCase {
waitForExpectations(timeout: 0.3) waitForExpectations(timeout: 0.3)
} }
func testManagerDoesNotCallConnectWhenConnectingWithLessThanOneReconnect() {
setUpSockets()
let expect = expectation(description: "The manager should not call connect on the engine")
expect.isInverted = true
let engine = TestEngine(client: manager, url: manager.socketURL, options: nil)
engine.onConnect = {
expect.fulfill()
}
manager.setTestStatus(.connecting)
manager.setCurrentReconnect(currentReconnect: 0)
manager.engine = engine
manager.connect()
waitForExpectations(timeout: 0.3)
}
func testManagerCallConnectWhenConnectingAndMoreThanOneReconnect() {
setUpSockets()
let expect = expectation(description: "The manager should call connect on the engine")
let engine = TestEngine(client: manager, url: manager.socketURL, options: nil)
engine.onConnect = {
expect.fulfill()
}
manager.setTestStatus(.connecting)
manager.setCurrentReconnect(currentReconnect: 1)
manager.engine = engine
manager.connect()
waitForExpectations(timeout: 0.8)
}
func testManagerCallsDisconnect() { func testManagerCallsDisconnect() {
setUpSockets() setUpSockets()
@ -154,6 +192,10 @@ public enum ManagerExpectation: String {
} }
public class TestManager: SocketManager { public class TestManager: SocketManager {
public func setCurrentReconnect(currentReconnect: Int) {
self.currentReconnectAttempt = currentReconnect
}
public override func disconnect() { public override func disconnect() {
setTestStatus(.disconnected) setTestStatus(.disconnected)
} }

View File

@ -487,7 +487,7 @@ class TestEngine: SocketEngineSpec {
private(set) var ws: WebSocket? = nil private(set) var ws: WebSocket? = nil
private(set) var version = SocketIOVersion.three private(set) var version = SocketIOVersion.three
fileprivate var onConnect: (() -> ())? internal var onConnect: (() -> ())?
required init(client: SocketEngineClient, url: URL, options: [String: Any]?) { required init(client: SocketEngineClient, url: URL, options: [String: Any]?) {
self.client = client self.client = client