From ec4378ca492179fe810a72dfbb50a7845f18bd35 Mon Sep 17 00:00:00 2001 From: Mark Schisler Date: Thu, 19 Aug 2021 09:30:29 -0500 Subject: [PATCH 1/7] Handling reconnect scenarios properly when socket is hung --- .gitignore | 2 + Source/SocketIO/Client/SocketIOClient.swift | 3 +- Source/SocketIO/Manager/SocketManager.swift | 5 +-- Tests/TestSocketIO/SocketAckManagerTest.swift | 1 - Tests/TestSocketIO/SocketMangerTest.swift | 42 +++++++++++++++++++ Tests/TestSocketIO/SocketSideEffectTest.swift | 2 +- 6 files changed, 49 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index aec6c75b..4c165233 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ Socket.IO-Test-Server/node_modules/* .idea/ docs/docsets/ docs/undocumented.json + +.swiftpm diff --git a/Source/SocketIO/Client/SocketIOClient.swift b/Source/SocketIO/Client/SocketIOClient.swift index 4debd560..d97bae1e 100644 --- a/Source/SocketIO/Client/SocketIOClient.swift +++ b/Source/SocketIO/Client/SocketIOClient.swift @@ -150,7 +150,8 @@ open class SocketIOClient: NSObject, SocketIOClientSpec { manager.handleQueue.asyncAfter(deadline: DispatchTime.now() + timeoutAfter) {[weak self] in 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.leaveNamespace() diff --git a/Source/SocketIO/Manager/SocketManager.swift b/Source/SocketIO/Manager/SocketManager.swift index c45c5f56..d69aa11f 100644 --- a/Source/SocketIO/Manager/SocketManager.swift +++ b/Source/SocketIO/Manager/SocketManager.swift @@ -132,7 +132,7 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat private(set) var reconnectAttempts = -1 private var _config: SocketIOClientConfiguration - private var currentReconnectAttempt = 0 + internal var currentReconnectAttempt = 0 private var reconnecting = false // MARK: Initializers @@ -186,9 +186,8 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat /// /// Override if you wish to attach a custom `SocketEngineSpec`. 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) - return } diff --git a/Tests/TestSocketIO/SocketAckManagerTest.swift b/Tests/TestSocketIO/SocketAckManagerTest.swift index f5d9c2a5..4f7f5b0c 100644 --- a/Tests/TestSocketIO/SocketAckManagerTest.swift +++ b/Tests/TestSocketIO/SocketAckManagerTest.swift @@ -28,7 +28,6 @@ class SocketAckManagerTest : XCTestCase { func testManagerTimeoutAck() { let callbackExpection = expectation(description: "Manager should timeout ack with noAck status") - let itemsArray = ["Hi", "ho"] func callback(_ items: [Any]) { XCTAssertEqual(items.count, 1, "Timed out ack should have one value") diff --git a/Tests/TestSocketIO/SocketMangerTest.swift b/Tests/TestSocketIO/SocketMangerTest.swift index 1fa72a0a..b2dd5715 100644 --- a/Tests/TestSocketIO/SocketMangerTest.swift +++ b/Tests/TestSocketIO/SocketMangerTest.swift @@ -60,6 +60,44 @@ class SocketMangerTest : XCTestCase { 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() { setUpSockets() @@ -154,6 +192,10 @@ public enum ManagerExpectation: String { } public class TestManager: SocketManager { + public func setCurrentReconnect(currentReconnect: Int) { + self.currentReconnectAttempt = currentReconnect + } + public override func disconnect() { setTestStatus(.disconnected) } diff --git a/Tests/TestSocketIO/SocketSideEffectTest.swift b/Tests/TestSocketIO/SocketSideEffectTest.swift index ecaaee03..749a819a 100644 --- a/Tests/TestSocketIO/SocketSideEffectTest.swift +++ b/Tests/TestSocketIO/SocketSideEffectTest.swift @@ -487,7 +487,7 @@ class TestEngine: SocketEngineSpec { private(set) var ws: WebSocket? = nil private(set) var version = SocketIOVersion.three - fileprivate var onConnect: (() -> ())? + internal var onConnect: (() -> ())? required init(client: SocketEngineClient, url: URL, options: [String: Any]?) { self.client = client From 8837d4a0d83d92d89c22234a6b30d6b337fddd5a Mon Sep 17 00:00:00 2001 From: humanfriend22 <75396937+humanfriend22@users.noreply.github.com> Date: Fri, 10 Mar 2023 04:03:36 +0000 Subject: [PATCH 2/7] correct SocketActStatus in example code --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e1273e6..6c701515 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ socket.on("currentAmount") {data, ack in guard let cur = data[0] as? Double else { return } socket.emitWithAck("canUpdate", cur).timingOut(after: 0) {data in - if data.first as? String ?? "passed" == SocketAckValue.noAck { + if data.first as? String ?? "passed" == SocketAckStatus.noAck { // Handle ack timeout } From a21af1016eb6eb322464ea918f698ea32681092e Mon Sep 17 00:00:00 2001 From: David K <34067963+davidkessler-ch@users.noreply.github.com> Date: Fri, 10 Nov 2023 23:49:06 +0100 Subject: [PATCH 3/7] fix never running timingOut due to weak self capture --- Source/SocketIO/Ack/SocketAckEmitter.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/SocketIO/Ack/SocketAckEmitter.swift b/Source/SocketIO/Ack/SocketAckEmitter.swift index 0306f298..18bebcfc 100644 --- a/Source/SocketIO/Ack/SocketAckEmitter.swift +++ b/Source/SocketIO/Ack/SocketAckEmitter.swift @@ -136,8 +136,8 @@ public final class OnAckCallback: NSObject { guard seconds != 0 else { return } - socket.manager?.handleQueue.asyncAfter(deadline: DispatchTime.now() + seconds) {[weak socket, weak self] in - guard let socket = socket, let `self` = self else { return } + socket.manager?.handleQueue.asyncAfter(deadline: DispatchTime.now() + seconds) {[weak socket] in + guard let socket = socket else { return } socket.ackHandlers.timeoutAck(self.ackNumber) } From 6dd51170bb11de3f91a5e083a7370eee70cb4c98 Mon Sep 17 00:00:00 2001 From: Jakub Olejnik Date: Tue, 21 Nov 2023 16:24:22 +0100 Subject: [PATCH 4/7] Bump Carthage deployment targets --- Socket.IO-Client-Swift.xcodeproj/project.pbxproj | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj index c899a6ed..ffed9326 100644 --- a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj +++ b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj @@ -652,6 +652,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = SocketIO/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -678,7 +679,7 @@ SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; - TVOS_DEPLOYMENT_TARGET = 10.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VALID_ARCHS = "$(inherited)"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -728,6 +729,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = SocketIO/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -752,7 +754,7 @@ SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; - TVOS_DEPLOYMENT_TARGET = 10.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VALID_ARCHS = "$(inherited)"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -832,7 +834,7 @@ "@loader_path/../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = "io.socket.$(PRODUCT_NAME:rfc1034identifier)"; @@ -842,7 +844,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = 10.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VALID_ARCHS = "$(inherited)"; }; name = Debug; @@ -914,7 +916,7 @@ "@loader_path/../Frameworks", ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "io.socket.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -922,7 +924,7 @@ SUPPORTED_PLATFORMS = "$(inherited)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = 10.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VALID_ARCHS = "$(inherited)"; }; name = Release; From eb806b62bfdd4763037a22ae9226a33cf50b530f Mon Sep 17 00:00:00 2001 From: Mpendulo Ndlovu Date: Mon, 18 Mar 2024 11:18:13 +0200 Subject: [PATCH 5/7] Bump minimum deployment target to iOS 12 to match Starscream dependency Currently there is an error when compiling for release: ``` Compiling for iOS 11.0, but module 'Starscream' has a minimum deployment target of iOS 12.0 ``` This pull request addresses this error by bumping the minimum deployment target to match Starscream. --- Socket.IO-Client-Swift.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Socket.IO-Client-Swift.podspec b/Socket.IO-Client-Swift.podspec index 243071f0..366c8e73 100644 --- a/Socket.IO-Client-Swift.podspec +++ b/Socket.IO-Client-Swift.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.homepage = "https://github.com/socketio/socket.io-client-swift" s.license = { :type => 'MIT' } s.author = { "Erik" => "nuclear.ace@gmail.com" } - s.ios.deployment_target = '11.0' + s.ios.deployment_target = '12.0' s.osx.deployment_target = '10.13' s.tvos.deployment_target = '12.0' s.watchos.deployment_target = '5.0' From 5ecc5bbae9f070f0568cbd0478e39be469e9398f Mon Sep 17 00:00:00 2001 From: Alessio Zap Boerio Date: Mon, 15 Apr 2024 13:39:56 +0200 Subject: [PATCH 6/7] Bump Starscream version to upToNextMajor 4.0.8 --- .../xcode/package.xcworkspace/contents.xcworkspacedata | 7 +++++++ Package.resolved | 4 ++-- Package.swift | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Package.resolved b/Package.resolved index de0432e5..b363050e 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/daltoniam/Starscream", "state": { "branch": null, - "revision": "ac6c0fc9da221873e01bd1a0d4818498a71eef33", - "version": "4.0.6" + "revision": "c6bfd1af48efcc9a9ad203665db12375ba6b145a", + "version": "4.0.8" } } ] diff --git a/Package.swift b/Package.swift index bf23db27..89729293 100644 --- a/Package.swift +++ b/Package.swift @@ -8,7 +8,7 @@ let package = Package( .library(name: "SocketIO", targets: ["SocketIO"]) ], dependencies: [ - .package(url: "https://github.com/daltoniam/Starscream", .exactItem("4.0.6")), + .package(url: "https://github.com/daltoniam/Starscream", .upToNextMajor(from: "4.0.8")), ], targets: [ .target(name: "SocketIO", dependencies: ["Starscream"]), From 354ed7e5e4792de254bc6bda2c27211affbd0e40 Mon Sep 17 00:00:00 2001 From: Shaojie Hong Date: Thu, 9 May 2024 16:58:16 +0800 Subject: [PATCH 7/7] Update SocketEngine.swift Fix the issue where it takes over 60 seconds to close the socket after a network disconnection, and the problem where the server-side socket takes over 30 seconds to close when the server ends a connection --- Source/SocketIO/Engine/SocketEngine.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/SocketIO/Engine/SocketEngine.swift b/Source/SocketIO/Engine/SocketEngine.swift index f95b828f..1d1c071d 100644 --- a/Source/SocketIO/Engine/SocketEngine.swift +++ b/Source/SocketIO/Engine/SocketEngine.swift @@ -761,6 +761,12 @@ extension SocketEngine { case .disconnected(_, _): wsConnected = false websocketDidDisconnect(error: nil) + case .viabilityChanged(false): + wsConnected = false + websocketDidDisconnect(error: nil) + case .peerClosed: + wsConnected = false + websocketDidDisconnect(error: nil) case let .text(msg): parseEngineMessage(msg) case let .binary(data):