From 992bc583eb1194a693139a6ce9403ed06b16cbd3 Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Mon, 9 Jan 2017 11:25:35 +0000 Subject: [PATCH] TR4i (#562) * ARTProtocolMessageFlag enum: use NS_OPTIONS to define a bitmask * TR4i * Fix: should indicate that the channel has been resumed or not (RESUMED flag) --- Source/ARTProtocolMessage+Private.h | 11 ++++++-- Source/ARTProtocolMessage.m | 12 +++++++-- Source/ARTRealtimeChannel.m | 4 +-- Spec/RealtimeClientChannel.swift | 39 +++++++++++++++++++++++++++++ Spec/RealtimeClientPresence.swift | 4 +-- 5 files changed, 62 insertions(+), 8 deletions(-) diff --git a/Source/ARTProtocolMessage+Private.h b/Source/ARTProtocolMessage+Private.h index d094a0aec..5812232e0 100644 --- a/Source/ARTProtocolMessage+Private.h +++ b/Source/ARTProtocolMessage+Private.h @@ -6,7 +6,12 @@ // Copyright (c) 2014 Ably. All rights reserved. // -NSString *__art_nonnull ARTProtocolMessageActionToStr(ARTProtocolMessageAction action); +/// ARTProtocolMessageFlag bitmask +typedef NS_OPTIONS(NSUInteger, ARTProtocolMessageFlag) { + ARTProtocolMessageFlagHasPresence = (1UL << 0), //1 + ARTProtocolMessageFlagHasBacklog = (1UL << 1), //2 + ARTProtocolMessageFlagResumed = (1UL << 2) //4 +}; ART_ASSUME_NONNULL_BEGIN @@ -15,7 +20,9 @@ ART_ASSUME_NONNULL_BEGIN @property (readwrite, assign, nonatomic) BOOL hasConnectionSerial; @property (readonly, assign, nonatomic) BOOL ackRequired; -- (BOOL)isSyncEnabled; +@property (readonly, assign, nonatomic) BOOL hasPresence; +@property (readonly, assign, nonatomic) BOOL hasBacklog; +@property (readonly, assign, nonatomic) BOOL resumed; - (BOOL)mergeFrom:(ARTProtocolMessage *)msg; diff --git a/Source/ARTProtocolMessage.m b/Source/ARTProtocolMessage.m index f73fcb433..54bec033e 100644 --- a/Source/ARTProtocolMessage.m +++ b/Source/ARTProtocolMessage.m @@ -107,8 +107,16 @@ - (BOOL)ackRequired { return self.action == ARTProtocolMessageMessage || self.action == ARTProtocolMessagePresence; } -- (BOOL)isSyncEnabled { - return self.flags & 0x1; +- (BOOL)hasPresence { + return self.flags & ARTProtocolMessageFlagHasPresence; +} + +- (BOOL)hasBacklog { + return self.flags & ARTProtocolMessageFlagHasBacklog; +} + +- (BOOL)resumed { + return self.flags & ARTProtocolMessageFlagResumed; } - (ARTConnectionDetails *)getConnectionDetails { diff --git a/Source/ARTRealtimeChannel.m b/Source/ARTRealtimeChannel.m index 74cc169a2..7189aeaf0 100644 --- a/Source/ARTRealtimeChannel.m +++ b/Source/ARTRealtimeChannel.m @@ -419,12 +419,12 @@ - (void)setAttached:(ARTProtocolMessage *)message { if (message.error != nil) { _errorReason = message.error; } - ARTChannelStateChange *stateChange = [[ARTChannelStateChange alloc] initWithCurrent:self.state previous:self.state event:ARTChannelEventUpdate reason:message.error]; + ARTChannelStateChange *stateChange = [[ARTChannelStateChange alloc] initWithCurrent:self.state previous:self.state event:ARTChannelEventUpdate reason:message.error resumed:message.resumed]; [self emit:stateChange.event with:stateChange]; return; } - if ([message isSyncEnabled]) { + if (message.hasPresence) { [self.presenceMap startSync]; [self.logger debug:__FILE__ line:__LINE__ message:@"R:%p C:%p PresenceMap Sync started", _realtime, self]; } diff --git a/Spec/RealtimeClientChannel.swift b/Spec/RealtimeClientChannel.swift index 1674e76e6..bea897f93 100644 --- a/Spec/RealtimeClientChannel.swift +++ b/Spec/RealtimeClientChannel.swift @@ -362,6 +362,45 @@ class RealtimeClientChannel: QuickSpec { } } + // RTL2f, TR4i + it("bit flag RESUMED was included") { + let options = AblyTests.commonAppSetup() + let client = ARTRealtime(options: options) + defer { client.dispose(); client.close() } + let channel = client.channels.get("test") + + waitUntil(timeout: testTimeout) { done in + channel.once(.Attached) { stateChange in + guard let stateChange = stateChange else { + fail("ChannelStageChange is nil"); done(); return + } + expect(stateChange.resumed).to(beFalse()) + expect(stateChange.reason).to(beNil()) + done() + } + channel.attach() + } + + let attachedMessage = ARTProtocolMessage() + attachedMessage.action = .Attached + attachedMessage.channel = "test" + attachedMessage.flags = 4 //Resumed + + waitUntil(timeout: testTimeout) { done in + channel.once(.Update) { stateChange in + guard let stateChange = stateChange else { + fail("ChannelStageChange is nil"); done(); return + } + expect(stateChange.resumed).to(beTrue()) + expect(stateChange.reason).to(beNil()) + expect(stateChange.current).to(equal(ARTRealtimeChannelState.Attached)) + expect(stateChange.previous).to(equal(ARTRealtimeChannelState.Attached)) + done() + } + client.transport?.receive(attachedMessage) + } + } + } // RTL3 diff --git a/Spec/RealtimeClientPresence.swift b/Spec/RealtimeClientPresence.swift index 2ac0dd29e..694343116 100644 --- a/Spec/RealtimeClientPresence.swift +++ b/Spec/RealtimeClientPresence.swift @@ -34,7 +34,7 @@ class RealtimeClientPresence: QuickSpec { let attached = transport.protocolMessagesReceived.filter({ $0.action == .Attached })[0] expect(attached.flags & 0x1).to(equal(0)) - expect(attached.isSyncEnabled()).to(beFalse()) + expect(attached.hasPresence).to(beFalse()) expect(channel.presence.syncComplete).to(beFalse()) expect(channel.presenceMap.syncComplete).to(beFalse()) } @@ -71,7 +71,7 @@ class RealtimeClientPresence: QuickSpec { // There are members present on the channel expect(attached.flags & 0x1).to(equal(1)) - expect(attached.isSyncEnabled()).to(beTrue()) + expect(attached.hasPresence).to(beTrue()) expect(channel.presence.syncComplete).toEventually(beTrue(), timeout: testTimeout)