实时GKMatch断开连接问题

时间:2013-01-13 00:00:17

标签: iphone ios xcode game-center

我使用GameCenter和实时服务器 - 客户端网络策略创建了一个纸牌游戏。在沙盒中进行测试时,游戏可以完美运行(进行连接,选择最佳主机,发送/接收数据),有时游戏实际上甚至可以完成。但是,大多数情况下,在两个设备上我都会收到一个匹配:player:didChangeState:回调通知我对方用户已断开连接。它经常令人沮丧地发生,并且似乎与不活动或超时没有任何关系。我的想法是我可能正在处理GameCenter服务器上的正常网络延迟,因为很少有情况下播放器似乎重新连接并再次发送数据。是否有其他人使用GKMatch和Real Time GameCenter处理这些问题?我正在iPhone 5和iPhone 4上测试应用程序,它们都运行iOS 6.1并连接到同一个wifi网络。

2 个答案:

答案 0 :(得分:1)

我对MAX player = 2有同样的问题。 对我来说GKMatch的代表

- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state; 

将'state'作为'GKPlayerStateDisconnected'返回,即使用户在游戏中处于活动状态。 解决方案对我有用如下: 在我的NetworkManager类中,我将当前匹配引用为gkMatch。因此,每当我再次将'state'作为'GKPlayerStateDisconnected'时,我正在检查它是否真的与远程播放器断开连接。为此,我使用'gkMatch'数据如下: ps:如果session实际上没有断开连接,它包含字符串'connected'。

NSString *gkMatchString = [NSString stringWithFormat:@"%@",[NetworkManager sharedManager].gkMatch];

        if ([gkMatchString rangeOfString:@"connected"].location == NSNotFound) 
          {
            NSLog(@"Session is actually closed.");
          }else{
            NSLog(@"Session is NOT yet closed.");
          }

它对我有用,所以让我知道它是否对任何人有帮助。

答案 1 :(得分:0)

虽然我没有找到断开连接的确切解决方案,但我用以下内容修补了我的问题。另外,为了防止丢失在断开连接期间发送的消息:我实现了一个“响应”处理程序,用于检测消息是否实际上是由对手接收的(因为当对手没有收到消息时,可靠数据发送模式不会出错)由于连接问题)。

当游戏开始时,我确定用户是主机(chooseBestHostPlayerWithCompletionHandler:^),当我检测到断开连接时,主机播放器重新邀请非服务器播放器返回游戏。无论游戏是通过邀请还是“立即游戏”启动,这都有效。它解决了我的“ShouldReconnect”问题,它只适用于1v1和邀请匹配。当非主机播放器接受邀请时,我以编程方式完成匹配,以防止MatchMakerViewController必须出现在屏幕上。重新连接后,比赛将立即恢复。

- (void)reinvitePlayer {
    GKMatchRequest *request = [[GKMatchRequest alloc] init];
    request.minPlayers = 2;
    request.maxPlayers = 2;
    request.playersToInvite = @[_opponent.playerID];
    request.inviteMessage = @"Reconnect?";
    request.inviteeResponseHandler = ^(NSString *playerID, GKInviteeResponse response)
    {
        DLog(@"Player response = %i.",response);
        // [self updateUIForPlayer: playerID accepted: (response == GKInviteeResponseAccepted)];
    };
    [[GKMatchmaker sharedMatchmaker] addPlayersToMatch:_match matchRequest:request completionHandler:^(NSError *error) {
        if (error != nil) {
            DLog(@"Unable to add player to match.");
        } else {
            DLog(@"Successfully reconnected");
            [[GKMatchmaker sharedMatchmaker] finishMatchmakingForMatch:_match];
        }
    }];
}