diff --git a/Source/ARTRealtime.m b/Source/ARTRealtime.m index f6e552133..ddb5f39ae 100644 --- a/Source/ARTRealtime.m +++ b/Source/ARTRealtime.m @@ -221,6 +221,20 @@ - (void)transition:(ARTRealtimeConnectionState)state withErrorInfo:(ARTErrorInfo _transport.delegate = self; [_transport connect]; } + + if (previousState == ARTRealtimeDisconnected) { + __GENERIC(NSArray, ARTQueuedMessage *) *pending = self.pendingMessages; + _pendingMessages = [[NSMutableArray alloc] init]; + for (ARTQueuedMessage *queued in pending) { + [self send:queued.msg callback:^(ARTStatus *__art_nonnull status) { + for (id cb in queued.cbs) { + ((void(^)(ARTStatus *__art_nonnull))cb)(status); + } + }]; + } + + } + break; case ARTRealtimeConnected: [self cancelSuspendTimer]; diff --git a/Spec/RealtimeClientConnection.swift b/Spec/RealtimeClientConnection.swift index a1fa8cd12..626266878 100644 --- a/Spec/RealtimeClientConnection.swift +++ b/Spec/RealtimeClientConnection.swift @@ -1701,6 +1701,43 @@ class RealtimeClientConnection: QuickSpec { } } + context("Transport disconnected side effects") { + + // RTN19a + it("should resend any ProtocolMessage that is awaiting a ACK/NACK") { + let options = AblyTests.commonAppSetup() + options.logLevel = .Debug + options.disconnectedRetryTimeout = 0.1 + let client = AblyTests.newRealtime(options) + defer { client.close() } + let channel = client.channels.get("test") + let transport = client.transport as! TestProxyTransport + + expect(client.connection.state).toEventually(equal(ARTRealtimeConnectionState.Connected), timeout: testTimeout) + + waitUntil(timeout: testTimeout) { done in + channel.attach { _ in done() } + } + + waitUntil(timeout: testTimeout) { done in + transport.ignoreSends = true + channel.publish(nil, data: "message") { error in + expect(error).to(beNil()) + let newTransport = client.transport as! TestProxyTransport + expect(transport.protocolMessagesReceived.filter{ $0.action == .Connected }).to(haveCount(1)) + expect(newTransport.protocolMessagesReceived.filter{ $0.action == .Connected }).to(haveCount(1)) + expect(transport.protocolMessagesSent.filter{ $0.action == .Message }).to(haveCount(0)) + expect(transport.protocolMessagesSentIgnored.filter{ $0.action == .Message }).to(haveCount(1)) + expect(newTransport.protocolMessagesSent.filter{ $0.action == .Message }).to(haveCount(1)) + done() + } + transport.ignoreSends = false + client.onDisconnected() + } + } + + } + } } } diff --git a/Spec/TestUtilities.swift b/Spec/TestUtilities.swift index ebec9063a..66c379857 100644 --- a/Spec/TestUtilities.swift +++ b/Spec/TestUtilities.swift @@ -492,6 +492,7 @@ class TestProxyTransport: ARTWebSocketTransport { private(set) var protocolMessagesSent = [ARTProtocolMessage]() private(set) var protocolMessagesReceived = [ARTProtocolMessage]() + private(set) var protocolMessagesSentIgnored = [ARTProtocolMessage]() private(set) var rawDataSent = [NSData]() private(set) var rawDataReceived = [NSData]() @@ -502,6 +503,7 @@ class TestProxyTransport: ARTWebSocketTransport { var afterProcessingReceivedMessage: Optional<(ARTProtocolMessage)->()> = nil var actionsIgnored = [ARTProtocolMessageAction]() + var ignoreSends = false override func setupWebSocket(params: [NSURLQueryItem], withOptions options: ARTClientOptions, resumeKey: String?, connectionSerial: NSNumber?) -> NSURL { let url = super.setupWebSocket(params, withOptions: options, resumeKey: resumeKey, connectionSerial: connectionSerial) @@ -510,6 +512,10 @@ class TestProxyTransport: ARTWebSocketTransport { } override func send(msg: ARTProtocolMessage) { + if ignoreSends { + protocolMessagesSentIgnored.append(msg) + return + } protocolMessagesSent.append(msg) if let performEvent = beforeProcessingSentMessage { performEvent(msg)