Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Completed tasks from Asana:

* CL-2091
* fixed one bug with subscription restore
* added delegate methods which will allow to inform about resubscription
  process
* implemented DNS killing logic
  • Loading branch information...
commit e6e517c4d5e4d4ef4d99c5b7c2375b22904cf869 1 parent 73fae69
@parfeon parfeon authored
Showing with 430 additions and 129 deletions.
  1. +2 −0  objective-c/3.4/pubnub.xcodeproj/project.pbxproj
  2. +81 −49 objective-c/3.4/pubnub/Classes/Controller/PNAppDelegate.m
  3. +3 −3 objective-c/3.4/pubnub/Classes/Controller/PNMainViewController.m
  4. +5 −5 objective-c/3.4/pubnub/Classes/Model/PNDataManager.m
  5. +0 −2  objective-c/3.4/pubnub/Classes/View/PNChannelInformationView.m
  6. +3 −3 objective-c/3.4/pubnub/libs/PubNub/Core/PNObservationCenter.h
  7. +34 −13 objective-c/3.4/pubnub/libs/PubNub/Core/PNObservationCenter.m
  8. +93 −27 objective-c/3.4/pubnub/libs/PubNub/Core/PubNub.m
  9. +26 −0 objective-c/3.4/pubnub/libs/PubNub/Data/PNConfiguration+Protected.h
  10. +21 −0 objective-c/3.4/pubnub/libs/PubNub/Data/PNConfiguration.m
  11. +5 −0 objective-c/3.4/pubnub/libs/PubNub/Data/PNError.m
  12. +3 −0  objective-c/3.4/pubnub/libs/PubNub/Misc/PNConstants.h
  13. +7 −0 objective-c/3.4/pubnub/libs/PubNub/Misc/PNMacro.h
  14. +10 −0 objective-c/3.4/pubnub/libs/PubNub/Misc/PNNotifications.h
  15. +28 −5 objective-c/3.4/pubnub/libs/PubNub/Misc/PNStructures.h
  16. +12 −0 objective-c/3.4/pubnub/libs/PubNub/Misc/Protocols/PNDelegate.h
  17. +6 −0 objective-c/3.4/pubnub/libs/PubNub/Misc/Protocols/PNMessageChannelDelegate.h
  18. +38 −18 objective-c/3.4/pubnub/libs/PubNub/Network/PNMessagingChannel.m
  19. +7 −0 objective-c/3.4/pubnub/libs/PubNub/Network/PNReachability.h
  20. +16 −0 objective-c/3.4/pubnub/libs/PubNub/Network/PNReachability.m
  21. +30 −4 objective-c/3.4/pubnub/libs/PubNub/Network/Transport/PNConnection.m
View
2  objective-c/3.4/pubnub.xcodeproj/project.pbxproj
@@ -329,6 +329,7 @@
DD71B9554CFFFD2A43343B36 /* PNChannelEvents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PNChannelEvents.h; sourceTree = "<group>"; };
DD71B967C56CA2E8F66085ED /* PNTimeTokenResponseParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PNTimeTokenResponseParser.m; sourceTree = "<group>"; };
DD71B96F17DA5856CFBA96A0 /* PNMessageHistoryRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PNMessageHistoryRequest.h; sourceTree = "<group>"; };
+ DD71BA0E2595B8F111648D33 /* PNConfiguration+Protected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PNConfiguration+Protected.h"; sourceTree = "<group>"; };
DD71BA90D925864CA27764CD /* pubnub-large2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pubnub-large2.png"; sourceTree = "<group>"; };
DD71BAA5E7F0263BCD399384 /* PNChannelEventsResponseParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PNChannelEventsResponseParser.h; sourceTree = "<group>"; };
DD71BACF5F9CB939AEA62A65 /* PNMessagesHistory+Protected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PNMessagesHistory+Protected.h"; sourceTree = "<group>"; };
@@ -785,6 +786,7 @@
DD71B286201A499AF1BF1146 /* PNMessagesHistory.m */,
DD71BFAB0FEB9AF00E5DE50C /* PNMessagesHistory.h */,
DD71BACF5F9CB939AEA62A65 /* PNMessagesHistory+Protected.h */,
+ DD71BA0E2595B8F111648D33 /* PNConfiguration+Protected.h */,
);
path = Data;
sourceTree = "<group>";
View
130 objective-c/3.4/pubnub/Classes/Controller/PNAppDelegate.m
@@ -53,39 +53,51 @@ - (void)initializePubNubClient {
if (!connected && error) {
- UIAlertView *infoAlertView = [UIAlertView new];
- infoAlertView.title = [NSString stringWithFormat:@"%@(%@)",
- [error localizedDescription],
- NSStringFromClass([self class])];
- infoAlertView.message = [NSString stringWithFormat:@"Reason:\n%@\nSuggestion:\n%@",
- [error localizedFailureReason],
- [error localizedRecoverySuggestion]];
- [infoAlertView addButtonWithTitle:@"OK"];
- [infoAlertView show];
+ PNLog(PNLogGeneralLevel, self, @"#2 PubNub client was unable to connect because of error: %@",
+ [error localizedDescription],
+ [error localizedFailureReason]);
}
}];
// Subscribe application delegate on subscription updates
// (events when client subscribe on some channel)
- [[PNObservationCenter defaultCenter] addClientChannelSubscriptionObserver:self
- withCallbackBlock:^(NSArray *channels,
- BOOL subscribed,
- PNError *subscriptionError) {
-
- if (subscribed) {
-
- PNLog(PNLogGeneralLevel, self,
- @"{BLOCK-P} PubNub client subscribed on channels: %@",
- channels);
- }
- else {
-
- PNLog(PNLogGeneralLevel, self,
- @"{BLOCK-P} PubNub client subscription failed with error: %@",
- subscriptionError);
- }
- }];
+ [[PNObservationCenter defaultCenter] addClientChannelSubscriptionStateObserver:self
+ withCallbackBlock:^(PNSubscriptionProcessState state,
+ NSArray *channels,
+ PNError *subscriptionError) {
+
+ switch (state) {
+
+ case PNSubscriptionProcessNotSubscribedState:
+
+ PNLog(PNLogGeneralLevel, self,
+ @"{BLOCK-P} PubNub client subscription failed with error: %@",
+ subscriptionError);
+ break;
+
+ case PNSubscriptionProcessSubscribedState:
+
+ PNLog(PNLogGeneralLevel, self,
+ @"{BLOCK-P} PubNub client subscribed on channels: %@",
+ channels);
+ break;
+
+ case PNSubscriptionProcessWillRestoreState:
+
+ PNLog(PNLogGeneralLevel, self,
+ @"{BLOCK-P} PubNub client will restore subscribed on channels: %@",
+ channels);
+ break;
+
+ case PNSubscriptionProcessRestoredState:
+
+ PNLog(PNLogGeneralLevel, self,
+ @"{BLOCK-P} PubNub client restores subscribed on channels: %@",
+ channels);
+ break;
+ }
+ }];
// Subscribe on message arrival events with block
[[PNObservationCenter defaultCenter] addMessageReceiveObserver:self
@@ -130,43 +142,36 @@ - (void)pubnubClient:(PubNub *)client error:(PNError *)error {
}
- (void)pubnubClient:(PubNub *)client willConnectToOrigin:(NSString *)origin {
-
- PNLog(PNLogGeneralLevel, self, @"PubNub client is about to connect to PubNub origin at: %@", origin);
+
if (self.isDisconnectedOnNetworkError) {
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Restoring connection"
- message:[NSString stringWithFormat:
- @"PubNub client will restore connection to %@ this will take some time",
- origin]
- delegate:nil
- cancelButtonTitle:nil
- otherButtonTitles:@"OK", nil];
- [alert show];
+ PNLog(PNLogGeneralLevel, self, @"PubNub client trying to restore connection to PubNub origin at: %@", origin);
+ }
+ else {
+
+ PNLog(PNLogGeneralLevel, self, @"PubNub client is about to connect to PubNub origin at: %@", origin);
}
}
- (void)pubnubClient:(PubNub *)client didConnectToOrigin:(NSString *)origin {
-
- PNLog(PNLogGeneralLevel, self, @"PubNub client successfully connected to PubNub origin at: %@", origin);
if (self.isDisconnectedOnNetworkError) {
- self.disconnectedOnNetworkError = NO;
+ PNLog(PNLogGeneralLevel, self, @"PubNub client restored connection to PubNub origin at: %@", origin);
+ }
+ else {
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Connection restored"
- message:[NSString stringWithFormat:
- @"PubNub client restored connection to %@", origin]
- delegate:nil
- cancelButtonTitle:nil
- otherButtonTitles:@"OK", nil];
- [alert show];
+ PNLog(PNLogGeneralLevel, self, @"PubNub client successfully connected to PubNub origin at: %@", origin);
}
+
+
+ self.disconnectedOnNetworkError = NO;
}
- (void)pubnubClient:(PubNub *)client connectionDidFailWithError:(PNError *)error {
- PNLog(PNLogGeneralLevel, self, @"PubNub client was unable to connect because of error: %@", error);
+ PNLog(PNLogGeneralLevel, self, @"#1 PubNub client was unable to connect because of error: %@", error);
self.disconnectedOnNetworkError = error.code == kPNClientConnectionFailedOnInternetFailureError;
}
@@ -193,6 +198,16 @@ - (void)pubnubClient:(PubNub *)client didSubscribeOnChannels:(NSArray *)channels
PNLog(PNLogGeneralLevel, self, @"PubNub client successfully subscribed on channels: %@", channels);
}
+- (void)pubnubClient:(PubNub *)client willRestoreSubscriptionOnChannels:(NSArray *)channels {
+
+ PNLog(PNLogGeneralLevel, self, @"PubNub client resuming subscription on: %@", channels);
+}
+
+- (void)pubnubClient:(PubNub *)client didRestoreSubscriptionOnChannels:(NSArray *)channels {
+
+ PNLog(PNLogGeneralLevel, self, @"PubNub client successfully restored subscription on channels: %@", channels);
+}
+
- (void)pubnubClient:(PubNub *)client subscriptionDidFailWithError:(NSError *)error {
PNLog(PNLogGeneralLevel, self, @"PubNub client failed to subscribe because of error: %@", error);
@@ -277,7 +292,24 @@ - (void) pubnubClient:(PubNub *)client
- (NSNumber *)shouldResubscribeOnConnectionRestore {
- return @(NO);
+ NSNumber *shouldResubscribeOnConnectionRestore = @(NO);
+
+ if ([[PubNub subscribedChannels] count] > 0) {
+
+ NSString *lastTimeToken = [[[PubNub subscribedChannels] lastObject] updateTimeToken];
+
+ if ([shouldResubscribeOnConnectionRestore boolValue]) {
+
+ lastTimeToken = @"0";
+ }
+
+ PNLog(PNLogGeneralLevel, self, @"PubNub client should restore subscription? %@. Resuming at last time token: %@",
+ ![shouldResubscribeOnConnectionRestore boolValue]?@"YES":@"NO",
+ lastTimeToken);
+ }
+
+
+ return shouldResubscribeOnConnectionRestore;
}
#pragma mark -
View
6 objective-c/3.4/pubnub/Classes/Controller/PNMainViewController.m
@@ -543,13 +543,13 @@ - (void)hideNoChannelSelectedMessage {
- (void)creationView:(PNChannelCreationView*)view subscribeOnChannel:(PNChannel *)channel {
- [PubNub subscribeOnChannel:channel withCompletionHandlingBlock:^(NSArray *channels,
- BOOL subscribed,
+ [PubNub subscribeOnChannel:channel withCompletionHandlingBlock:^(PNSubscriptionProcessState state,
+ NSArray *channels,
PNError *subscriptionError) {
NSString *alertMessage = [NSString stringWithFormat:@"Subscribed on channel: %@\nTo be able to send messages, select channel from righthand list",
channel.name];
- if (!subscribed) {
+ if (state == PNSubscriptionProcessNotSubscribedState) {
alertMessage = [NSString stringWithFormat:@"Failed to subscribe on: %@", channel.name];
}
View
10 objective-c/3.4/pubnub/Classes/Model/PNDataManager.m
@@ -71,12 +71,12 @@ - (id)init {
self.subscribedChannelsList = [NSMutableArray array];
PNDataManager *weakSelf = self;
- [[PNObservationCenter defaultCenter] addClientChannelSubscriptionObserver:self
- withCallbackBlock:^(NSArray *channels,
- BOOL subscribed,
- PNError *subscriptionError) {
+ [[PNObservationCenter defaultCenter] addClientChannelSubscriptionStateObserver:self
+ withCallbackBlock:^(PNSubscriptionProcessState state,
+ NSArray *channels,
+ PNError *subscriptionError) {
- if (subscribed) {
+ if (state == PNSubscriptionProcessSubscribedState || state == PNSubscriptionProcessRestoredState) {
NSArray *unsortedList = [PubNub subscribedChannels];
NSSortDescriptor *nameSorting = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
View
2  objective-c/3.4/pubnub/Classes/View/PNChannelInformationView.m
@@ -8,9 +8,7 @@
#import "PNChannelInformationView.h"
-#import "PNMacro.h"
#import "PNDataManager.h"
-#import "PNChannelInformationDelegate.h"
#pragma mark Private interface methods
View
6 objective-c/3.4/pubnub/libs/PubNub/Core/PNObservationCenter.h
@@ -48,9 +48,9 @@
* Add/remove observer which would like to know when PubNub client
* subscribes/unsubscribe on/from channel
*/
-- (void)addClientChannelSubscriptionObserver:(id)observer
- withCallbackBlock:(PNClientChannelSubscriptionHandlerBlock)callbackBlock;
-- (void)removeClientChannelSubscriptionObserver:(id)observer;
+- (void)addClientChannelSubscriptionStateObserver:(id)observer
+ withCallbackBlock:(PNClientChannelSubscriptionHandlerBlock)callbackBlock;
+- (void)removeClientChannelSubscriptionStateObserver:(id)observer;
- (void)addClientChannelUnsubscriptionObserver:(id)observer
withCallbackBlock:(PNClientChannelUnsubscriptionHandlerBlock)callbackBlock;
- (void)removeClientChannelUnsubscriptionObserver:(id)observer;
View
47 objective-c/3.4/pubnub/libs/PubNub/Core/PNObservationCenter.m
@@ -175,6 +175,14 @@ - (id)init {
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleClientSubscriptionProcess:)
+ name:kPNClientSubscriptionWillRestoreNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(handleClientSubscriptionProcess:)
+ name:kPNClientSubscriptionDidRestoreNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(handleClientSubscriptionProcess:)
name:kPNClientSubscriptionDidFailNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -338,7 +346,7 @@ - (void)removeClientConnectionStateObserver:(id)observer oneTimeEvent:(BOOL)isOn
#pragma mark - Client channels action/event observation
-- (void)addClientChannelSubscriptionObserver:(id)observer
+- (void)addClientChannelSubscriptionStateObserver:(id)observer
withCallbackBlock:(PNClientChannelSubscriptionHandlerBlock)callbackBlock {
@@ -348,7 +356,7 @@ - (void)addClientChannelSubscriptionObserver:(id)observer
withBlock:callbackBlock];
}
-- (void)removeClientChannelSubscriptionObserver:(id)observer {
+- (void)removeClientChannelSubscriptionStateObserver:(id)observer {
[self removeObserver:observer forEvent:PNObservationEvents.clientSubscriptionOnChannels oneTimeEvent:NO];
}
@@ -618,22 +626,35 @@ - (void)handleClientConnectionStateChange:(NSNotification *)notification {
}
- (void)handleClientSubscriptionProcess:(NSNotification *)notification {
-
+
+
NSArray *channels = nil;
PNError *error = nil;
- BOOL subscribed = NO;
-
- if ([notification.name isEqualToString:kPNClientSubscriptionDidCompleteNotification]) {
+ PNSubscriptionProcessState state = PNSubscriptionProcessNotSubscribedState;
+
+ // Check whether arrived notification that subscription failed or not
+ if ([notification.name isEqualToString:kPNClientSubscriptionDidFailNotification]) {
- subscribed = YES;
-
- channels = (NSArray *)notification.userInfo;
- }
- else {
-
error = (PNError *)notification.userInfo;
channels = error.associatedObject;
}
+ else {
+
+ // Retrieve list of channels on which event is occurred
+ channels = (NSArray *)notification.userInfo;
+ state = PNSubscriptionProcessSubscribedState;
+
+ // Check whether arrived notification that subscription will be restored
+ if ([notification.name isEqualToString:kPNClientSubscriptionWillRestoreNotification]) {
+
+ state = PNSubscriptionProcessWillRestoreState;
+ }
+ // Check whether arrived notification that subscription restored
+ else if ([notification.name isEqualToString:kPNClientSubscriptionDidRestoreNotification]) {
+
+ state = PNSubscriptionProcessRestoredState;
+ }
+ }
// Retrieving list of observers (including one time and persistent observers)
@@ -646,7 +667,7 @@ - (void)handleClientSubscriptionProcess:(NSNotification *)notification {
PNClientChannelSubscriptionHandlerBlock block = [observerData valueForKey:PNObservationObserverData.observerCallbackBlock];
if (block) {
- block(channels, subscribed, error);
+ block(state, channels, error);
}
}];
View
120 objective-c/3.4/pubnub/libs/PubNub/Core/PubNub.m
@@ -26,6 +26,7 @@
#import "PNServiceChannel.h"
#import "PNRequestsImport.h"
#import "PNHereNowRequest.h"
+#import "PNConfiguration+Protected.h"
#pragma mark Static
@@ -189,6 +190,12 @@ - (void)notifyDelegateAboutParticipantsListDownloadFailedWithError:(PNError *)er
*/
- (void)notifyDelegateAboutError:(PNError *)error;
+/**
+ * This method allow notify delegate that client is about to close
+ * connection because of speficied error
+ */
+- (void)notifyDelegateClientWillDisconnectWithError:(PNError *)error;
+
- (void)sendNotification:(NSString *)notificationName withObject:(id)object;
/**
@@ -379,12 +386,18 @@ + (void)disconnect {
[[PNObservationCenter defaultCenter] removeClientAsMessageProcessingObserver];
[[PNObservationCenter defaultCenter] removeClientAsSubscriptionObserver];
[[PNObservationCenter defaultCenter] removeClientAsUnsubscribeObserver];
+
+ [[self sharedInstance].configuration shouldKillDNSCache:NO];
}
// Mark that client is disconnecting from remote PubNub services on
// user request (or by internal client request when updating configuration)
[self sharedInstance].state = PNPubNubClientStateDisconnecting;
+ // Reset client runtime flags and properties
+ [self sharedInstance].connectOnServiceReachabilityCheck = NO;
+ [self sharedInstance].restoringConnection = NO;
+
// Empty connection pool after connection will
// be closed
@@ -975,10 +988,15 @@ - (id)init {
// Adding PubNub services availability observer
__block __pn_desired_weak PubNub *weakSelf = self;
self.reachability.reachabilityChangeHandleBlock = ^(BOOL connected) {
+
+ PNLog(PNLogGeneralLevel, weakSelf, @"IS CONNECTED? %@ (STATE: %i)", connected?@"YES":@"NO", weakSelf.state);
if (weakSelf.shouldConnectOnServiceReachabilityCheck) {
-
- [[weakSelf class] connect];
+
+ if (connected) {
+
+ [[weakSelf class] connect];
+ }
}
else {
@@ -1005,6 +1023,8 @@ - (id)init {
[weakSelf handleConnectionErrorOnNetworkFailure];
}
else {
+ PNError *connectionError = [PNError errorWithCode:kPNClientConnectionClosedOnInternetFailureError];
+ [weakSelf notifyDelegateClientWillDisconnectWithError:connectionError];
weakSelf.state = PNPubNubClientStateDisconnectingOnNetworkError;
@@ -1113,8 +1133,27 @@ - (void)connectionChannel:(PNConnectionChannel *)channel didConnectToHost:(NSStr
[self warmUpConnection];
+ [self notifyDelegateAboutConnectionToOrigin:host];
+
if (self.isRestoringConnection) {
+ NSArray *channels = [self.messagingChannel subscribedChannels];
+
+ if ([channels count] > 0) {
+
+ // Notify delegate that client is about to restore subscription
+ // on previously subscribed channels
+ if ([self.delegate respondsToSelector:@selector(pubnubClient:willRestoreSubscriptionOnChannels:)]) {
+
+ [self.delegate performSelector:@selector(pubnubClient:willRestoreSubscriptionOnChannels:)
+ withObject:self
+ withObject:channels];
+ }
+
+ [self sendNotification:kPNClientSubscriptionWillRestoreNotification withObject:channels];
+ }
+
+
BOOL shouldResubscribe = self.configuration.shouldResubscribeOnConnectionRestore;
if ([self.delegate respondsToSelector:@selector(shouldResubscribeOnConnectionRestore)]) {
@@ -1122,11 +1161,11 @@ - (void)connectionChannel:(PNConnectionChannel *)channel didConnectToHost:(NSStr
}
[self.messagingChannel restoreSubscription:shouldResubscribe];
+
+
}
self.restoringConnection = NO;
-
- [self notifyDelegateAboutConnectionToOrigin:host];
}
}
@@ -1138,6 +1177,8 @@ - (void)connectionChannel:(PNConnectionChannel *)channel
// communication channels not connected to the server
if(self.state == PNPubNubClientStateConnecting && [self.configuration.origin isEqualToString:host] &&
![self.messagingChannel isConnected] && ![self.serviceChannel isConnected]) {
+
+ [self.configuration shouldKillDNSCache:YES];
if ([self.delegate respondsToSelector:@selector(pubnubClient:connectionDidFailWithError:)]) {
@@ -1178,7 +1219,6 @@ - (void)connectionChannel:(PNConnectionChannel *)channel didDisconnectFromOrigin
PNPubNubClientState state = PNPubNubClientStateDisconnected;
if (self.state == PNPubNubClientStateDisconnectingOnNetworkError) {
-
state = PNPubNubClientStateDisconnectedOnNetworkError;
}
self.state = state;
@@ -1284,23 +1324,19 @@ - (void)connectionChannel:(PNConnectionChannel *)channel
disconnectedOnNetworkError = error.code == kPNRequestExecutionFailedOnInternetFailureError;
}
+ if (!disconnectedOnNetworkError) {
+
+ disconnectedOnNetworkError = ![self.messagingChannel isConnected] || ![self.serviceChannel isConnected];
+ }
if (disconnectedOnNetworkError) {
self.state = PNPubNubClientStateDisconnectingOnNetworkError;
}
-
-
- if ([self.delegate respondsToSelector:@selector(pubnubClient:willDisconnectWithError:)]) {
-
- [self.delegate performSelector:@selector(pubnubClient:willDisconnectWithError:)
- withObject:self
- withObject:error];
- }
-
- [self sendNotification:kPNClientConnectionDidFailWithErrorNotification withObject:error];
+ [self.reachability updateReachabilityFromError:error];
+ [self notifyDelegateClientWillDisconnectWithError:error];
}
}
@@ -1308,19 +1344,23 @@ - (void)connectionChannel:(PNConnectionChannel *)channel
#pragma mark - Handler methods
- (void)handleConnectionErrorOnNetworkFailure {
-
- PNError *networkError = [PNError errorWithCode:kPNClientConnectionFailedOnInternetFailureError];
-
- // Notify delegate about connection error if delegate
- // implemented error handling delegate method
- if ([self.delegate respondsToSelector:@selector(pubnubClient:connectionDidFailWithError:)]) {
-
- [self.delegate performSelector:@selector(pubnubClient:connectionDidFailWithError:)
- withObject:self
- withObject:networkError];
- }
- [self sendNotification:kPNClientConnectionDidFailWithErrorNotification withObject:networkError];
+ // Check whether client is connectig currently or not
+ if (self.state = PNPubNubClientStateConnecting) {
+
+ PNError *networkError = [PNError errorWithCode:kPNClientConnectionFailedOnInternetFailureError];
+
+ // Notify delegate about connection error if delegate
+ // implemented error handling delegate method
+ if ([self.delegate respondsToSelector:@selector(pubnubClient:connectionDidFailWithError:)]) {
+
+ [self.delegate performSelector:@selector(pubnubClient:connectionDidFailWithError:)
+ withObject:self
+ withObject:networkError];
+ }
+
+ [self sendNotification:kPNClientConnectionDidFailWithErrorNotification withObject:networkError];
+ }
}
@@ -1434,6 +1474,18 @@ - (void)notifyDelegateAboutError:(PNError *)error {
[self sendNotification:kPNClientErrorNotification withObject:error];
}
+- (void)notifyDelegateClientWillDisconnectWithError:(PNError *)error {
+
+ if ([self.delegate respondsToSelector:@selector(pubnubClient:willDisconnectWithError:)]) {
+
+ [self.delegate performSelector:@selector(pubnubClient:willDisconnectWithError:)
+ withObject:self
+ withObject:error];
+ }
+
+ [self sendNotification:kPNClientConnectionDidFailWithErrorNotification withObject:error];
+}
+
- (void)sendNotification:(NSString *)notificationName withObject:(id)object {
// Send notification to all who is interested in it
@@ -1492,6 +1544,20 @@ - (void)messagingChannel:(PNMessagingChannel *)channel didSubscribeOnChannels:(N
[self sendNotification:kPNClientSubscriptionDidCompleteNotification withObject:channels];
}
+- (void)messagingChannel:(PNMessagingChannel *)messagingChannel didRestoreSubscriptionOnChannels:(NSArray *)channels {
+
+ // Check whether delegate can handle subscription restore on channels or not
+ if ([self.delegate respondsToSelector:@selector(pubnubClient:didRestoreSubscriptionOnChannels:)]) {
+
+ [self.delegate performSelector:@selector(pubnubClient:didRestoreSubscriptionOnChannels:)
+ withObject:self
+ withObject:channels];
+ }
+
+
+ [self sendNotification:kPNClientSubscriptionDidRestoreNotification withObject:channels];
+}
+
- (void) messagingChannel:(PNMessagingChannel *)channel
didFailSubscribeOnChannels:(NSArray *)channels
withError:(PNError *)error {
View
26 objective-c/3.4/pubnub/libs/PubNub/Data/PNConfiguration+Protected.h
@@ -0,0 +1,26 @@
+//
+// PNConfiguration+Protected.h
+// pubnub
+//
+// Created by Sergey Mamontov on 02/18/13.
+//
+//
+
+#import "PNConfiguration.h"
+
+
+@interface PNConfiguration (Protected)
+
+
+#pragma mark Instance methods
+
+/**
+ * Set whether configuration should provide DNS killing
+ * remote origin address or not
+ */
+- (void)shouldKillDNSCache:(BOOL)shouldKillDNSCache;
+
+#pragma mark -
+
+
+@end
View
21 objective-c/3.4/pubnub/libs/PubNub/Data/PNConfiguration.m
@@ -24,6 +24,10 @@ @interface PNConfiguration ()
// Stores reference on services host name
@property (nonatomic, copy) NSString *origin;
+// Stores reference on original origin host address
+// (this property is used when DNS killer is required)
+@property (nonatomic, copy) NSString *realOrigin;
+
// Stores reference on keys which is required
// to establish connection and send packets to it
@property (nonatomic, copy) NSString *publishKey;
@@ -100,6 +104,7 @@ - (id)initWithOrigin:(NSString *)originHostName
if((self = [super init])) {
self.origin = ([originHostName length] > 0)?originHostName:kPNDefaultOriginHost;
+ self.realOrigin = self.origin;
self.publishKey = publishKey?publishKey:@"";
self.subscriptionKey = subscribeKey?subscribeKey:@"";
self.secretKey = secretKey?secretKey:@"0";
@@ -141,6 +146,22 @@ - (BOOL)requiresConnectionResetWithConfiguration:(PNConfiguration *)configuratio
return shouldReset;
}
+- (void)shouldKillDNSCache:(BOOL)shouldKillDNSCache {
+
+ if (shouldKillDNSCache) {
+
+ NSString *subDomain = [self.realOrigin stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@".%@",
+ kPNServiceMainDomain]
+ withString:@""];
+
+ self.origin = [NSString stringWithFormat:@"%@-%d.%@", subDomain, PNRandomInteger(), kPNServiceMainDomain];
+ }
+ else {
+
+ self.origin = self.realOrigin;
+ }
+}
+
- (BOOL)isValid {
BOOL isValid = YES;
View
5 objective-c/3.4/pubnub/libs/PubNub/Data/PNError.m
@@ -153,6 +153,10 @@ - (NSString *)localizedDescription {
errorDescription = @"PubNub client connection failed";
break;
+ case kPNClientConnectionClosedOnInternetFailureError:
+
+ errorDescription = @"PubNub client connection lost connection";
+ break;
case kPNRequestExecutionFailedOnInternetFailureError:
case kPNRequestExecutionFailedClientNotReadyError:
@@ -215,6 +219,7 @@ - (NSString *)localizedFailureReason {
failureReason = @"Looks like client lost connection while trying to connect to remote PubNub service";
break;
case kPNRequestExecutionFailedOnInternetFailureError:
+ case kPNClientConnectionClosedOnInternetFailureError:
failureReason = @"Looks like client lost connection";
break;
View
3  objective-c/3.4/pubnub/libs/PubNub/Misc/PNConstants.h
@@ -32,6 +32,9 @@ static NSString * const kPNClientName = @"Obj-C-MacOS";
// API version on the flight
static NSString * const kPNRequestAPIVersionPrefix = @"";
+// Stores reference on PubNub service domain
+static NSString * const kPNServiceMainDomain = @"pubnub.com";
+
#if __IPHONE_OS_VERSION_MIN_REQUIRED
static NSString * const kPNDefaultOriginHost = @"ios.pubnub.com";
#elif __MAC_OS_X_VERSION_MIN_REQUIRED
View
7 objective-c/3.4/pubnub/libs/PubNub/Misc/PNMacro.h
@@ -14,6 +14,7 @@
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonHMAC.h>
#import "NSData+PNAdditions.h"
+#include <stdlib.h>
#ifndef PNMacro_h
@@ -216,5 +217,11 @@ BOOL PNIsUserGeneratedUUID(NSString *uuid) {
return ![generatedUUIDCheckPredicate evaluateWithObject:uuid];
}
+static NSInteger PNRandomInteger();
+NSInteger PNRandomInteger() {
+
+ return (arc4random() %(INT32_MAX)-1);
+}
+
#endif
View
10 objective-c/3.4/pubnub/libs/PubNub/Misc/PNNotifications.h
@@ -44,6 +44,16 @@ static NSString * const kPNClientConnectionDidFailWithErrorNotification = @"PNCl
// in userInfo like plain NSArray)
static NSString * const kPNClientSubscriptionDidCompleteNotification = @"PNClientSubscriptionDidCompleteNotification";
+// Sent when PubNub client is about to restore subscription on
+// specified channel(s) (channel(s) will be passed
+// in userInfo like plain NSArray)
+static NSString * const kPNClientSubscriptionWillRestoreNotification = @"PNClientSubscriptionWillRestoreNotification";
+
+// Sent when PubNub client was able to restore subscription on
+// specified channel(s) (channel(s) will be passed
+// in userInfo like plain NSArray)
+static NSString * const kPNClientSubscriptionDidRestoreNotification = @"PNClientSubscriptionDidRestoreNotification";
+
// Sent when PubNub client was unable to subscribe on
// specified channel(s) (error will be passed in
// userInfo and channel(s) will be passed in associatedObject
View
33 objective-c/3.4/pubnub/libs/PubNub/Misc/PNStructures.h
@@ -77,20 +77,43 @@ typedef enum _PNPresenceEventType {
} PNPresenceEventType;
// This enum represent list of possible
-// events which can occurre during requests
+// events which can occur during requests
// execution
typedef enum _PNOperationResultEvent {
- // Stores unknown event
- PNOperationResultUnknown,
- PNOperationResultLeave = PNPresenceEventLeave
+ // Stores unknown event
+ PNOperationResultUnknown,
+ PNOperationResultLeave = PNPresenceEventLeave
} PNOperationResultEvent;
+// This enum represents list of possible
+// subscription states which can occur while
+// client subscribing/restoring
+typedef enum _PNSubscriptionProcessState {
+
+ // Not subscribed state (maybe some error
+ // occurred while tried to subscribe)
+ PNSubscriptionProcessNotSubscribedState,
+
+ // Subscribed state
+ PNSubscriptionProcessSubscribedState,
+
+ // Will restore subscription
+ // (called right after connection
+ // restored)
+ PNSubscriptionProcessWillRestoreState,
+
+ // Restored subscription after connection
+ // restored
+ PNSubscriptionProcessRestoredState
+} PNSubscriptionProcessState;
+
+
typedef void (^PNClientConnectionSuccessBlock)(NSString *);
typedef void (^PNClientConnectionFailureBlock)(PNError *);
typedef void (^PNClientConnectionStateChangeBlock)(NSString *, BOOL, PNError *);
-typedef void (^PNClientChannelSubscriptionHandlerBlock)(NSArray *, BOOL, PNError *);
+typedef void (^PNClientChannelSubscriptionHandlerBlock)(PNSubscriptionProcessState state, NSArray *, PNError *);
typedef void (^PNClientChannelUnsubscriptionHandlerBlock)(NSArray *, PNError *);
typedef void (^PNClientTimeTokenReceivingCompleteBlock)(NSNumber *, PNError *);
typedef void (^PNClientMessageProcessingBlock)(PNMessageState, id);
View
12 objective-c/3.4/pubnub/libs/PubNub/Misc/Protocols/PNDelegate.h
@@ -74,6 +74,18 @@
- (void)pubnubClient:(PubNub *)client didSubscribeOnChannels:(NSArray *)channels;
/**
+ * Called on delegate when client is about to init resubscribe on
+ * previous set of channels
+ */
+- (void)pubnubClient:(PubNub *)client willRestoreSubscriptionOnChannels:(NSArray *)channels;
+
+/**
+ * Called on delegate when client successfully restored subscription on
+ * previous set of channels
+ */
+- (void)pubnubClient:(PubNub *)client didRestoreSubscriptionOnChannels:(NSArray *)channels;
+
+/**
* Called on delegate when some kind of error occurred during
* subscription creation
* error - returned error will contain information about channel
View
6 objective-c/3.4/pubnub/libs/PubNub/Misc/Protocols/PNMessageChannelDelegate.h
@@ -27,6 +27,12 @@
- (void)messagingChannel:(PNMessagingChannel *)messagingChannel didSubscribeOnChannels:(NSArray *)channels;
/**
+ * Sent to the delegate when client successfully
+ * restored subscription on previous set of channels
+ */
+- (void)messagingChannel:(PNMessagingChannel *)messagingChannel didRestoreSubscriptionOnChannels:(NSArray *)channels;
+
+/**
* Sent to the delegate when client failed to subscribe
* on channels because of error
*/
View
56 objective-c/3.4/pubnub/libs/PubNub/Network/PNMessagingChannel.m
@@ -43,6 +43,10 @@ @interface PNMessagingChannel ()
// on which this client is subscribed now
@property (nonatomic, strong) NSMutableSet *subscribedChannelsSet;
+// Stores flag on whether messaging channel is restoring
+// subscription on previous channels or not
+@property (nonatomic, assign, getter = isRestoringSubscription) BOOL restoringSubscription;
+
#pragma mark - Instance methods
@@ -58,13 +62,6 @@ - (void)processResponse:(PNResponse *)response forRequest:(PNBaseRequest *)reque
#pragma mark - Channels management
/**
- * Same as -resubscribe but allow to specify whether
- * action was called by user request or not
- * (affect on notification chain)
- */
-- (void)resubscribeByUserRequest:(BOOL)resubscribeByUserRequest;
-
-/**
* Same function as -unsubscribeFromChannelsWithPresenceEvent:
* but also allow to specify whether leave was triggered by user
* or not
@@ -210,6 +207,8 @@ - (void)disconnectWithReset:(BOOL)shouldResetCommunicationChannel {
// Forward to the super class
[super disconnect];
+ self.restoringSubscription = NO;
+
// Check whether communication channel should reset state or not
if (shouldResetCommunicationChannel) {
@@ -266,6 +265,7 @@ - (void)leaveChannels:(NSArray *)channels byUserRequest:(BOOL)isLeavingByUserReq
[self scheduleRequest:[PNLeaveRequest leaveRequestForChannels:channelsForUnsubscribe
byUserRequest:isLeavingByUserRequest]
shouldObserveProcessing:YES];
+
}
}
@@ -284,6 +284,8 @@ - (BOOL)isSubscribedForChannel:(PNChannel *)channel {
- (void)resubscribe {
+ self.restoringSubscription = NO;
+
// Ensure that client connected to at least one channel
if ([self.subscribedChannelsSet count] > 0) {
@@ -296,20 +298,23 @@ - (void)resubscribe {
}
}
-- (void)resubscribeByUserRequest:(BOOL)resubscribeByUserRequest {
-}
-
- (void)restoreSubscription:(BOOL)shouldResubscribe {
- if (shouldResubscribe) {
+ if ([self.subscribedChannelsSet count]) {
- // Reset last update time token for channels in list
- [self.subscribedChannelsSet makeObjectsPerformSelector:@selector(resetUpdateTimeToken)];
- }
+ if (shouldResubscribe) {
- [self scheduleRequest:[PNSubscribeRequest subscribeRequestForChannels:[self.subscribedChannelsSet allObjects]
- byUserRequest:YES]
- shouldObserveProcessing:YES];
+ // Reset last update time token for channels in list
+ [self.subscribedChannelsSet makeObjectsPerformSelector:@selector(resetUpdateTimeToken)];
+ }
+
+ self.restoringSubscription = YES;
+
+
+ [self scheduleRequest:[PNSubscribeRequest subscribeRequestForChannels:[self.subscribedChannelsSet allObjects]
+ byUserRequest:YES]
+ shouldObserveProcessing:shouldResubscribe];
+ }
}
- (void)updateSubscription {
@@ -319,6 +324,8 @@ - (void)updateSubscription {
- (void)updateSubscriptionForChannels:(NSArray *)channels {
+ self.restoringSubscription = NO;
+
// Ensure that client connected to at least one channel
if ([channels count] > 0) {
@@ -337,6 +344,8 @@ - (void)subscribeOnChannels:(NSArray *)channels {
- (void)subscribeOnChannels:(NSArray *)channels withPresenceEvent:(BOOL)withPresenceEvent {
+ self.restoringSubscription = NO;
+
// Checking whether client already subscribed on one of
// channels from set or not
NSMutableSet *channelsSet = [[self channelsWithPresenceFromList:channels] mutableCopy];
@@ -376,6 +385,7 @@ - (NSArray *)unsubscribeFromChannelsWithPresenceEvent:(BOOL)withPresenceEvent {
- (NSArray *)unsubscribeFromChannelsWithPresenceEvent:(BOOL)withPresenceEvent
byUserRequest:(BOOL)isLeavingByUserRequest {
+ self.restoringSubscription = NO;
NSArray *subscribedChannels = [self.subscribedChannelsSet allObjects];
// Check whether should generate 'leave' presence event
@@ -589,6 +599,17 @@ - (void)handleEventOnChannelsForRequest:(PNSubscribeRequest *)request withRespon
- (void)handleSubscribeUnsubscribeRequestCompletion:(PNBaseRequest *)request {
+ // Check whether channel is restoring subscription on previously
+ // subscribed channels or not
+ if (self.isRestoringSubscription) {
+
+ self.restoringSubscription = NO;
+
+ [self.messagingDelegate performSelector:@selector(messagingChannel:didRestoreSubscriptionOnChannels:)
+ withObject:self
+ withObject:[self subscribedChannels]];
+ }
+
// Prepare selectors which will be pulled on delegate and
// list of subscribed channels
SEL delegateSelector = @selector(messagingChannel:didSubscribeOnChannels:);
@@ -746,7 +767,6 @@ - (void)requestsQueue:(PNRequestsQueue *)queue willSendRequest:(PNBaseRequest *)
request.resourcePath);
- // Check whether this is 'Leave' request or not
if ([request isKindOfClass:[PNLeaveRequest class]]) {
// Check whether connection should be closed for resubscribe
View
7 objective-c/3.4/pubnub/libs/PubNub/Network/PNReachability.h
@@ -56,6 +56,13 @@
*/
- (BOOL)isServiceAvailable;
+/**
+ * Allow to update current reachability state according to the
+ * error object (there is some situation when sockets may go down
+ * on network error long before reachability will notice this)
+ */
+- (void)updateReachabilityFromError:(PNError *)error;
+
#pragma mark -
View
16 objective-c/3.4/pubnub/libs/PubNub/Network/PNReachability.m
@@ -263,6 +263,22 @@ - (BOOL)isServiceAvailable {
}
+- (void)updateReachabilityFromError:(PNError *)error {
+
+ if ([self isServiceAvailable]) {
+
+ switch (error.code) {
+
+ case kPNClientConnectionFailedOnInternetFailureError:
+ case kPNClientConnectionClosedOnInternetFailureError:
+ case kPNRequestExecutionFailedOnInternetFailureError:
+
+ self.status = PNReachabilityStatusNotReachable;
+ break;
+ }
+ }
+}
+
#pragma mark - Memory management
View
34 objective-c/3.4/pubnub/libs/PubNub/Network/Transport/PNConnection.m
@@ -72,6 +72,9 @@ @interface PNConnection ()
// request from queue or not
@property (nonatomic, assign, getter = shouldProcessNextRequest) BOOL processNextRequest;
+// Stores flag on whether connecion is closing or not
+@property (nonatomic, assign, getter = isClosingConnection) BOOL closingConnection;
+
// Stores whether connection instance is reconnecting at
// this moment (which will mean that it should automatically
// open connection after full close)
@@ -593,6 +596,17 @@ - (BOOL)isConnectionIssuesError:(CFErrorRef)error {
break;
}
}
+ else if ([errorDomain isEqualToString:(NSString *)kCFErrorDomainCFNetwork]) {
+
+ switch (CFErrorGetCode(error)) {
+
+ case kCFHostErrorHostNotFound:
+ case kCFHostErrorUnknown:
+
+ isConnectionIssue = YES;
+ break;
+ }
+ }
return isConnectionIssue;
@@ -654,6 +668,8 @@ - (BOOL)prepareStreams {
- (void)closeStreams {
+ self.closingConnection = YES;
+
// Clean up cached data
[self unscheduleRequestsExecution];
_proxySettings = nil;
@@ -1228,7 +1244,8 @@ - (void)handleStreamError:(CFErrorRef)error shouldCloseConnection:(BOOL)shouldCl
[self reconnect];
}
}
- else if ([errorDomain isEqualToString:(NSString *)kCFErrorDomainPOSIX]) {
+ else if ([errorDomain isEqualToString:(NSString *)kCFErrorDomainPOSIX] ||
+ [errorDomain isEqualToString:(NSString *)kCFErrorDomainCFNetwork]) {
// Check whether connection should be reconnected
// because of critical error
@@ -1258,9 +1275,12 @@ - (void)handleStreamError:(CFErrorRef)error shouldCloseConnection:(BOOL)shouldCl
if (shouldCloseConnection) {
- [self.delegate connection:self willDisconnectFromHost:self.configuration.origin withError:errorObject];
+ if (!self.isClosingConnection) {
- [self closeStreams];
+ [self.delegate connection:self willDisconnectFromHost:self.configuration.origin withError:errorObject];
+
+ [self closeStreams];
+ }
}
else {
@@ -1368,7 +1388,13 @@ - (PNError *)processStreamError:(CFErrorRef)error {
if ([self isConnectionIssuesError:error]) {
- errorInstance = [PNError errorWithCode:kPNRequestExecutionFailedOnInternetFailureError];
+ int errorCode = kPNClientConnectionClosedOnInternetFailureError;
+ if (self.writeBuffer != nil && [self.writeBuffer hasData] && self.writeBuffer.isSendingBytes) {
+
+ errorCode = kPNRequestExecutionFailedOnInternetFailureError;
+ }
+
+ errorInstance = [PNError errorWithCode:errorCode];
}
else {
Please sign in to comment.
Something went wrong with that request. Please try again.