2013-06-07 8 views
11

私はGKMatchをかなりの期間アプリで使用しています。私は追いかけられていて、時々停止してゲームに出てきて、送信されたパケットを追跡したが受信しなかった。これはたまにしか起こらないが、私はそれがなぜ起こるのかを追跡できないようだ。Game Center GKMatch GKSendDataReliableパケットが紛失しました

すべてのメッセージは、GKSendDataReliableを使用して送信されます。

ロギングでは、パケットが1つのデバイスから正常に送信されていますが、ターゲットデバイスでは受信されません。

//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]; 
} 

何が起こる参照して、定期的に(多分1 100内のメッセージ) '「sendDataToAllPlayers」メソッドからエラーなしで送信されますが、受信デバイスがヒットされることはありませんということですdidReceiveData 'メソッドを呼び出します。私の理解は、GKSendDataReliableを使用すると、メッセージを送信し、肯定応答を受け取るまで別のメッセージを送信しないはずです。メッセージは受信されませんが、新しいメッセージは同じデバイスから送信されます。

送信メソッドは「はい」を返し、エラーはnilですが、didReceiveDataは決してヒットしません...!

誰もこれを見たことがありますか?誰にもこれが何であるか考えていますか?私はこれをデバッグするために他に何ができるのか分かりません。

+0

ユーザーは、ゲーム中に一部のデータが誤って失われている可能性もあると不平を言う。しかし、私はまだ自分自身でこのバグを再現することはできません。このバグが一貫して再現可能なサンプルプロジェクトがありますか?はいの場合は、共有してもらえますか?ありがとう。 – Yan

+0

私のプロジェクトは非常に大きく(現時点では店内のアクティブなアプリですが)、一貫して再現可能かどうかを調べるために小さなバージョンをまとめてみます。 –

+1

私は同じ問題を抱えています。特に、いずれかのデバイスのインターネット接続が弱い場合。 GKSendDataReliableが肯定応答を受け取るまでメッセージの送信を停止するのは本当ですか? – jyek

答えて

8

私はこのバグを確認します。 問題を一貫して再現するサンプルプロジェクトを作成しました:https://github.com/rabovik/GKMatchPacketLostExample。弱いインターネット接続(iOS 6.1.3でWi-FiとiPhone 4S、EDGEを搭載したiPad 3)でテストしました.Get Center APIからエラーがなくても定期的に失われるパケットもあります。さらに、デバイスはデータの受信を停止し、別のデバイスは依然としてメッセージを正常に送受信します。

バグが存在することが確認された場合、唯一可能な回避策は、信頼性の高い配送のために追加のトランスポートレイヤーを追加することです。

私はこの目的のための単純なlib:https://github.com/rabovik/RoUTPを書きました。送信されたすべてのメッセージを受信ごとに保存し、失われたものを再送信し、シーケンスが破損した場合に受信したメッセージをバッファします。 私のテストでは、 "RoUTP + GKMatchSendDataUnreliable"は "RoUTP + GKMatchSendDataReliable"よりも優れています(純粋なGKMatchSendDataReliableよりも信頼性がありません)。

+0

iOS 9でRoUTPが壊れているようです。それを使用してデータを送信した場合、すべてのデバイスでデータが受信されるわけではありません。私が信頼性の高い、または信頼できない輸送手段を使用するかどうかは関係ありません。私がRoUTPを無効にすると、すべて正常に動作します。 –

1

[編集:RoUTPはもはやiOS9で正しく動作するようです]

私は、パケットロスがoccuringた私の無線LANの範囲の端に昨日いくつかのテストをしました。 GKMatchSendDataReliableを使用してパケットが失われると、プレーヤーはGKMatchセッションから突然切断されます。 match:player:didChangeStateがGKPlayerStateDisconnectedで呼び出され、playerIDがplayerIDs辞書から削除されます。これはわずかなパケット損失でのみ発生します。私はまだこの接続からインターネットを閲覧することができます。

ここで、パケットを信頼できない方法で送信すると、match:player:didChangeStateは決して起動せず、問題は起こりません(重要な場合があるパケットを失うことを除いて)。パケット損失が相当になった場合にのみ切断されます。ここでYanのRoUTPライブラリは便利です。なぜなら、若干のパケット損失に遭遇したときにプレーヤーを切断することなく、これらの重要なメッセージを追跡して再試行できるからです。

また、GKMatchSendDataReliableを使用したデータ送信は、メッセージが正常に配信待ちの場合にのみYESを返します。メッセージが正常に配信されたかどうかはわかりません。どうした?それはすぐに戻る。

+0

ねえ、かなり複雑なrtsゲームに取り組んできました。あなたが描いている問題にはっきりと気づいています。私はRoUTPライブラリを試してみることをお勧めしますか? –

+0

これは間違いなく動作しますが、非常に基本的です。たとえば、すべてのパケットはRoUTPを使用してから送信する必要があります。そして、パケットを永遠に配信しようとし続けます。これは、遅延パケットのバーストを一斉に流す可能性があります。私は、ピアツーピアの代わりにフルクライアントサーバーに行き、RoUTPを捨てることを検討するかもしれません。クライアントがパケットを失って接続が切断された場合、パケットが急増したため誰かが反応する前にプレイヤーが他のプレイヤーを殺してしまうのではなく、他のクライアントのゲームを正常に保つことが望ましい結果になるかもしれません。 –

+0

また、その情報が破棄されたときに、どのパケットを誰が送信するのかはわかりません。したがって、char配列を使用して、playerIDをメッセージにエンコードする必要があります。すべてのプレイヤーがすべてのメッセージを受信するので、クライアントサーバーに行くと理想的ではありません。つまり、特定のプレイヤーにメッセージを送信することはできません。すべてのプレイヤーにのみ、プレイヤーには意図していないメッセージは無視されます。 –

関連する問題