diff --git a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift index 668fcdf37d..ff48c23e9b 100644 --- a/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift +++ b/AmplifyPlugins/API/Sources/AWSAPIPlugin/AppSyncRealTimeClient/AppSyncRealTimeClient.swift @@ -292,7 +292,7 @@ actor AppSyncRealTimeClient: AppSyncRealTimeClientProtocol { subject.filter { switch $0 { case .success(let response): return response.id == id || response.type == .connectionError - case .failure(let error): return true + case .failure: return true } } .map { result -> AppSyncSubscriptionEvent? in @@ -430,7 +430,7 @@ extension AppSyncRealTimeClient { } } - private func monitorHeartBeats(_ connectionAck: JSONValue?) { + internal func monitorHeartBeats(_ connectionAck: JSONValue?) { let timeoutMs = connectionAck?.connectionTimeoutMs?.intValue ?? 0 log.debug("[AppSyncRealTimeClient] Starting heart beat monitor with interval \(timeoutMs) ms") let cancellable = heartBeats.eraseToAnyPublisher() diff --git a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift index 83c2c58216..99b36943f1 100644 --- a/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift +++ b/AmplifyPlugins/API/Tests/AWSAPIPluginTests/AppSyncRealTimeClient/AppSyncRealTimeClientTests.swift @@ -551,4 +551,32 @@ class AppSyncRealTimeClientTests: XCTestCase { await fulfillment(of: [startTriggered, errorReceived], timeout: 2) } + + func testReconnect_whenHeartBeatSignalIsNotReceived() async throws { + var cancellables = Set() + let timeout = 1.0 + let mockWebSocketClient = MockWebSocketClient() + let mockAppSyncRequestInterceptor = MockAppSyncRequestInterceptor() + let appSyncClient = AppSyncRealTimeClient( + endpoint: URL(string: "https://example.com")!, + requestInterceptor: mockAppSyncRequestInterceptor, + webSocketClient: mockWebSocketClient + ) + + // start monitoring + await appSyncClient.monitorHeartBeats(.object([ + "connectionTimeoutMs": 100 + ])) + + let reconnect = expectation(description: "webSocket triggers event to connection") + await mockWebSocketClient.actionSubject.sink { action in + switch action { + case .connect: + reconnect.fulfill() + default: break + } + }.store(in: &cancellables) + await fulfillment(of: [reconnect], timeout: 2) + } + }