Code Monkey home page Code Monkey logo

Comments (11)

traderd65 avatar traderd65 commented on August 20, 2024

Hi Saurabh,

I'm opening a ticket for you at help.pubnub.com and will follow up there.

from objective-c.

definelabs avatar definelabs commented on August 20, 2024

I think I have found the issue, though I am not sure if this is intentional or a bug

If PubNub delegate implements

- (void)pubnubClient:(PubNub *)client didDisconnectFromOrigin:(NSString *)origin withError:(PNError *)error {
    PNLog(PNLogGeneralLevel, self, @"PubNub client closed connection because of error: %@", error);
}

then there is no issue, however if delegate does not implement this reconnection does not happen in the following scenario

1.go to background
2.lock device
3.unlock by sliding
4.come to foreground

Issue I think lies in this piece of code in PubNub.m

- (void)connectionChannel:(PNConnectionChannel *)channel didDisconnectFromOrigin:(NSString *)host {

    // Check whether host name arrived or not
    // (it may not arrive if event sending instance
    // was dismissed/deallocated)
    if (host == nil) {

        host = self.configuration.origin;
    }


    // Check whether received event from same host on which client
    // is configured or not and all communication channels are closed
    if([self.configuration.origin isEqualToString:host] &&
       ![self.messagingChannel isConnected] && ![self.serviceChannel isConnected]) {

        // Check whether all communication channels disconnected and whether
        // client in corresponding state or not
        if (self.state == PNPubNubClientStateDisconnecting ||
            self.state == PNPubNubClientStateDisconnectingOnNetworkError) {

            PNPubNubClientState state = PNPubNubClientStateDisconnected;
            if (self.state == PNPubNubClientStateDisconnectingOnNetworkError) {

                state = PNPubNubClientStateDisconnectedOnNetworkError;
            }
            self.state = state;

            SEL selectorForCheck = @selector(pubnubClient:didDisconnectFromOrigin:);
            if (state == PNPubNubClientStateDisconnectedOnNetworkError) {

                selectorForCheck = @selector(pubnubClient:didDisconnectFromOrigin:withError:);
            }
            if ([self.delegate respondsToSelector:selectorForCheck]) {

                if (self.state == PNPubNubClientStateDisconnected) {

                    [self.delegate pubnubClient:self didDisconnectFromOrigin:host];

                    [self sendNotification:kPNClientDidDisconnectFromOriginNotification withObject:host];
                }
                else {

                    PNError *connectionError = [PNError errorWithCode:kPNClientConnectionClosedOnInternetFailureError];

                    if ([self.delegate respondsToSelector:@selector(pubnubClient:didDisconnectFromOrigin:withError:)]) {

                        [self.delegate pubnubClient:self didDisconnectFromOrigin:host withError:connectionError];
                    }

                    [self sendNotification:kPNClientConnectionDidFailWithErrorNotification withObject:connectionError];


                    // Check whether error is caused by network error or not
                    switch (connectionError.code) {
                        case kPNClientConnectionFailedOnInternetFailureError:
                        case kPNClientConnectionClosedOnInternetFailureError:

                            // Try to refresh reachability state (there is situation when reachability state
                            // changed within library to handle sockets timeout/error)
                            [self.reachability refreshReachabilityState];
                            break;

                        default:
                            break;
                    }
                }
            }


            if(self.state == PNPubNubClientStateDisconnected) {

                // Clean up cached data
                [PNChannel purgeChannelsCache];
            }
            else {

                // Check whether service is available
                // (this event may arrive after device was unlocked
                // so basically connection is available and only
                // sockets closed by remote server or internal kernel
                // layer)
                if ([self.reachability isServiceReachabilityChecked] && [self.reachability isServiceAvailable]) {

                    // Check whether should restore connection or not
                    if ([self shouldRestoreConnection]) {

                        self.restoringConnection = YES;

                        // Try to restore connection to remote PubNub services
                        [[self class] connect];
                    }
                }
            }
        }
        // Check whether server unexpectedly closed connection
        // while client was active or not
        else if(self.state == PNPubNubClientStateConnected) {

            self.state = PNPubNubClientStateDisconnected;

            if([self shouldRestoreConnection]) {

                // Try to restore connection to remote PubNub services
                [[self class] connect];
            }
        }
        // Check whether connection has been closed because
        // PubNub client updates it's configuration
        else if (self.state == PNPubNubClientStateDisconnectingOnConfigurationChange) {

            // Close connection to PubNub services
            [[self class] disconnect];


            // Delay connection restore to give some time internal
            // components to complete their tasks
            int64_t delayInSeconds = 1;
            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
            dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {

                self.state = PNPubNubClientStateCreated;
                self.configuration = self.temporaryConfiguration;
                self.temporaryConfiguration = nil;

                [self prepareCryptoHelper];


                // Restore connection which will use new configuration
                [[self class] connect];
            });
        }
    }
}

[self.reachability refreshReachabilityState]; is only called if delegate implements didDisconnectFromOrigin:withError:

from objective-c.

parfeon avatar parfeon commented on August 20, 2024

Check response on #8 maybe it solved this issue as well.

from objective-c.

parfeon avatar parfeon commented on August 20, 2024

But thanks about refreshReachabilityState, will fix that

from objective-c.

definelabs avatar definelabs commented on August 20, 2024

I already tried github-8, I has same issue

from objective-c.

geremyCohen avatar geremyCohen commented on August 20, 2024

@definelabs we are checking it out now...

from objective-c.

parfeon avatar parfeon commented on August 20, 2024

Hi @definelabs
Can you check 'github-6' branch? I just can reproduce your issue on iPad with 3G connection.
But your research was very useful to help us find logic issue.

from objective-c.

definelabs avatar definelabs commented on August 20, 2024

Hi,

github-6 does not work

 PNError *connectionError;
            PNPubNubClientState state = PNPubNubClientStateDisconnected;
            if (self.state == PNPubNubClientStateDisconnectingOnNetworkError) {
                state = PNPubNubClientStateDisconnectedOnNetworkError;
            }
            self.state = state;

            SEL selectorForCheck = @selector(pubnubClient:didDisconnectFromOrigin:);
            if (state == PNPubNubClientStateDisconnectedOnNetworkError) {

                selectorForCheck = @selector(pubnubClient:didDisconnectFromOrigin:withError:);
            }
            if ([self.delegate respondsToSelector:selectorForCheck]) {

                if (self.state == PNPubNubClientStateDisconnected) {

                    [self.delegate pubnubClient:self didDisconnectFromOrigin:host];

                    [self sendNotification:kPNClientDidDisconnectFromOriginNotification withObject:host];
                }
                else {

                    connectionError = [PNError errorWithCode:kPNClientConnectionClosedOnInternetFailureError];

                    [self.delegate pubnubClient:self didDisconnectFromOrigin:host withError:connectionError];

                    [self sendNotification:kPNClientConnectionDidFailWithErrorNotification withObject:connectionError];
                }
            }


            // Check whether error is caused by network error or not
            switch (connectionError.code) {
                case kPNClientConnectionFailedOnInternetFailureError:
                case kPNClientConnectionClosedOnInternetFailureError:

                    // Try to refresh reachability state (there is situation whem reachability state
                    // changed within library to handle sockets timeout/error)
                    [self.reachability refreshReachabilityState];
                    break;

                default:
                    break;
            }

Again connectionError is only being initialized if delegate is implemented. In switch case, connectionError is null if delegate is not implemented, hence [self.reachability refreshReachabilityState]; is not called and reconnection does not happen

from objective-c.

stephenlb avatar stephenlb commented on August 20, 2024

Thank you for the report we are taking a look at the latest updates and the code you pasted.

On Apr 1, 2013, at 5:27 AM, Define Labs [email protected] wrote:

Hi,

github-6 does not work

PNError *connectionError;
PNPubNubClientState state = PNPubNubClientStateDisconnected;
if (self.state == PNPubNubClientStateDisconnectingOnNetworkError) {
state = PNPubNubClientStateDisconnectedOnNetworkError;
}
self.state = state;

        SEL selectorForCheck = @selector(pubnubClient:didDisconnectFromOrigin:);
        if (state == PNPubNubClientStateDisconnectedOnNetworkError) {

            selectorForCheck = @selector(pubnubClient:didDisconnectFromOrigin:withError:);
        }
        if ([self.delegate respondsToSelector:selectorForCheck]) {

            if (self.state == PNPubNubClientStateDisconnected) {

                [self.delegate pubnubClient:self didDisconnectFromOrigin:host];

                [self sendNotification:kPNClientDidDisconnectFromOriginNotification withObject:host];
            }
            else {

                connectionError = [PNError errorWithCode:kPNClientConnectionClosedOnInternetFailureError];

                [self.delegate pubnubClient:self didDisconnectFromOrigin:host withError:connectionError];

                [self sendNotification:kPNClientConnectionDidFailWithErrorNotification withObject:connectionError];
            }
        }


        // Check whether error is caused by network error or not
        switch (connectionError.code) {
            case kPNClientConnectionFailedOnInternetFailureError:
            case kPNClientConnectionClosedOnInternetFailureError:

                // Try to refresh reachability state (there is situation whem reachability state
                // changed within library to handle sockets timeout/error)
                [self.reachability refreshReachabilityState];
                break;

            default:
                break;
        }

Again connectionError is only being initialized if delegate is implemented. In switch case, connectionError is null if delegate is not implemented, hence [self.reachability refreshReachabilityState]; is not called and reconnection does not happen


Reply to this email directly or view it on GitHub.

from objective-c.

parfeon avatar parfeon commented on August 20, 2024

My bad :/
@definelabs Can you try latest fix from github-6 branch?

from objective-c.

definelabs avatar definelabs commented on August 20, 2024

It works now 👍

from objective-c.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.