【问题标题】:GKSession peer disconnect causes other peers to appear disconnectedGKSession 对等断开导致其他对等出现断开连接
【发布时间】:2011-12-04 19:56:34
【问题描述】:

我的应用使用 GKSession 和 GKSessionModePeer。它必须处理任意连接和断开的对等点,因为这是一个长时间运行的应用程序,用户应该能够进入后台并稍后再回来。这在大多数情况下都可以正常工作。但有时,当对等方断开连接时,其他设备会收到 didChangeState:GKPeerStateDisconnected 通知,不仅对于真正断开连接的设备,而且对于实际仍连接的其他设备。

我可以使用下面的代码和 4 台设备(全部在 iOS 5 上)重现此行为。当一切按预期进行时,当设备 A 退出应用程序时,所有其他设备都会收到通知,并且这些设备上的日志输出为:

Service: didChangeState: peer A disconnected (12345)

但是一段时间后,当一个设备断开连接时(再说一次 A),其他设备会收到未断开连接的设备的额外回调。例如,设备 C 会得到:

Service: didChangeState: peer A disconnected (...) // expected

Service: didChangeState: peer B disconnected (...) // never disconnected

大约在同一时间,我有时会在断开设备的日志中看到这类消息,不清楚它们是否真的相关:

dnssd_clientstub DNSServiceRefDeallocate called with NULL DNSServiceRef

和/或

dnssd_clientstub DNSServiceProcessResult called with DNSServiceRef with no ProcessReply function

一旦发生这种情况,GKSession 似乎处于不良状态,不再正确处理连接和断开连接。为了恢复良好状态,我必须在所有设备上硬杀应用程序,稍等片刻,然后重新开始。

我尝试了不同的方式在进入后台时处理 GKSession(仅设置 available=NO 并且不断开连接,根本不做任何事情),没有一个更好。

有没有其他人遇到过这种行为(并解决了它)?

AppDelegate 中的简单重现案例(使用 arc):

- (void)startGKSession 
{
    self.gkSession = [[GKSession alloc] initWithSessionID:nil displayName:nil sessionMode:GKSessionModePeer];
    gkSession.disconnectTimeout = 10;
    gkSession.delegate = self;
        gkSession.available = YES;
}

- (void)shutdownGKSession 
{
    gkSession.available = NO;
    [gkSession disconnectFromAllPeers];
    gkSession.delegate = nil;    
    gkSession = nil;
    [self.connectedDevices removeAllObjects];
}

- (void)connectToPeer:(NSString *)peerId 
{
    [gkSession connectToPeer:peerId withTimeout:10];
}

- (void)session:(GKSession *)session peer:(NSString *)peerId didChangeState:(GKPeerConnectionState)state 
{

        switch (state) {
                case GKPeerStateAvailable:
            NSLog(@"Service: didChangeState: peer %@ available, connecting (%@)", [session displayNameForPeer:peerId], peerId);
            [self performSelector:@selector(connectToPeer:) withObject:peerId afterDelay:.5];            
                        break;

                case GKPeerStateUnavailable:
                        NSLog(@"Service: didChangeState: peer %@ unavailable (%@)", [session displayNameForPeer:peerId], peerId);
                        break;

                case GKPeerStateConnected:
            NSLog(@"Service: didChangeState: peer %@ connected (%@)", [session displayNameForPeer:peerId], peerId);
                        break;

                case GKPeerStateDisconnected:
                        NSLog(@"Service: didChangeState: peer %@ disconnected (%@)", [session displayNameForPeer:peerId], peerId);
                        break;

                case GKPeerStateConnecting:
                        NSLog(@"Service: didChangeState: peer %@ connecting (%@)", [session displayNameForPeer:peerId], peerId);
                        break;
        }
}

- (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID 
{
    [session acceptConnectionFromPeer:peerID error:nil];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.connectedDevices = [[NSMutableArray alloc] init];
    [self startGKSession];

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{    
    [self shutdownGKSession];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [self startGKSession];
}

@end

【问题讨论】:

    标签: iphone objective-c ios gksession


    【解决方案1】:

    我从 Apple 支持部门获悉,之所以会出现这种断开连接行为,是因为设备“通过”彼此连接。例如,设备 A 通过设备 B 连接到设备 C。如果设备 B 掉线,设备 A 将看到设备 C 断开连接并立即重新连接。我还没有听说是否/何时会解决此问题。

    【讨论】:

      【解决方案2】:

      这可能为时已晚,但我认为如果您将会话模式从 服务器上的 GKSessionModePeer 到 GKSessionModeServer 将解决问题。

      基本上,它们都相互连接,服务器在技术上以相同的方式工作,但您会收到适当的断开连接通知。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-28
        • 2019-10-12
        • 1970-01-01
        • 2012-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多