我已经在应用程序中成功使用 GKMatch 很长一段时间了。我一直在追查并解决游戏偶尔停止的问题,并将其追踪到已发送但未收到的数据包。这种情况只是偶尔发生,但我似乎无法找出它发生的原因。
所有消息都使用 GKSendDataReliable 发送。
日志记录显示数据包已从一台设备成功发送,但目标设备从未收到。
//Code sample of sending method....
//self.model.match is a GKMatch instance
-(BOOL) sendDataToAllPlayers:(NSData *)data error:(NSError **)error {
[self.model.debugger addToLog:@"GKManager - sending data"];
return [self.model.match sendDataToAllPlayers:data withDataMode:GKSendDataReliable error:error];
}
...
//Code sample of receiving method....
// The match received data sent from the player.
-(void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
[self.model.debugger addToLog:@"GKManager - received data"];
[super didReceiveData:data fromPlayer:playerID];
}
我看到的情况是,“sendDataToAllPlayers”方法会定期(可能 100 条消息中有 1 条消息)无误地发送,但接收设备永远不会点击“didReceiveData”方法。我的理解是,使用 GKSendDataReliable 应该发送消息,然后在收到确认之前不会发送另一条消息。未收到消息,但从同一设备发送了新消息。
发送方法返回 'YES' 并且错误为 nil,但是 didReceiveData 永远不会被命中...!
有人见过吗?有谁知道这可能是什么?我不知道我还能做些什么来调试它。
最佳答案
我确认了错误。 我做了一个示例项目,不断重现这个问题:https://github.com/rabovik/GKMatchPacketLostExample .我在较弱的互联网连接(带 Wi-Fi 的 iPad 3 和带 EDGE 的 iPhone 4S;均在 iOS 6.1.3 上)上对其进行了测试,一些数据包经常丢失,而 Game Center API 没有任何错误。此外,有时设备停止接收任何数据,而另一个设备仍能成功发送和接收消息。
因此,如果我们确定存在错误,唯一可能的解决方法是添加一个额外的传输层以实现真正可靠的传输。
我为此编写了一个简单的库:https://github.com/rabovik/RoUTP .它保存所有发送的消息,直到对每个接收到的消息进行确认,重新发送丢失的消息并在序列中断的情况下缓冲接收到的消息。 在我的测试组合中,“RoUTP + GKMatchSendDataUnreliable”的效果甚至比“RoUTP + GKMatchSendDataReliable”更好(当然也比纯 GKMatchSendDataReliable 好,后者并不可靠)。
关于ios - Game Center GKMatch GKSendDataReliable丢包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16987880/