gpt4 book ai didi

iphone - GKSession peer disconnect 导致其他 peers 看起来断开连接

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:46:16 26 4
gpt4 key购买 nike

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

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

服务:didChangeState:peer A 断开连接 (12345)

但过了一段时间,当一个设备断开连接时(再说一次 A),其他设备将获得未断开连接的设备的额外回调。例如,设备 C 将获得:

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

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

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

dnssd_clientstub 使用 NULL DNSServiceRef 调用 DNSServiceRefDeallocate

和/或

dnssd_clientstub 使用没有 ProcessReply 函数的 DNSServiceRef 调用 DNSServiceProcessResult

一旦发生这种情况,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

最佳答案

我从 Apple 支持人员那里听说,这种断开连接行为的发生是因为设备“通过”彼此连接。例如,设备 A 通过设备 B 连接到设备 C。如果设备 B 掉线,设备 A 会看到设备 C 断开并立即重新连接。我还没有听说这个问题是否/何时会得到解决。

关于iphone - GKSession peer disconnect 导致其他 peers 看起来断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8378169/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com