I need to exchange small amounts of data in my app near realtime between users who could be anywhere with only an internet connection. One user is a Leader and needs to send data (just a few bytes) to all Followers - up to 30 - about each second. Then each Follower needs to send data (again, just a few bytes) back to the Leader about each second. The requirement is similar to the example app from last year's WWDC networking part 2 video called TicTacToe, except the users may not be local.
I've tried using Game Center but can't get it right. I've been able to achieve most of my objectives with this GameKit implementation:
Follower starts:
[[GKLocalPlayer localPlayer] registerListener:self];
request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playerAttributes = 0x0000000F;
request.playerGroup = groupName;
[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request...
Leader starts:
[[GKLocalPlayer localPlayer] registerListener:self];
request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playerAttributes = 0xFFFFFFF0;
request.playerGroup = groupName;
[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request...
You can update UI with the completion handlers, but don't count on a real match until:
- (void)match:(GKMatch *)match
player:(GKPlayer *)player
didChangeConnectionState:(GKPlayerConnectionState)state
{
use the match / player combo to note the connection for both leader and follower. Add to array of followers
for leader. If Leader, call your Leader starts code again
}
Send data to either with:
[match sendData:encoder.encodedData toPlayers:playerArray dataMode:GKMatchSendData(Un)reliableerror:&error];
and receive in:
- (void)match:(GKMatch *)match
didReceiveData:(NSData *)data
forRecipient:(GKPlayer *)recipient
fromRemotePlayer:(GKPlayer *)player
{ // you've got mail from player!
}
So far, so good. Here's the bad news: depending on network strength, connections disconnect regularly. Even though I've built in dependable reconnect code, it can take up to 15 seconds to reconnect so it really isn't a good "real-time" experience.
I'm currently testing with various combinations of data size (sometimes pad it so it's heft may keep the connection) or frequency (sometimes just send a "poke me" message) or tweaking the reliable vs unreliable flag in the send message calls.
I can get about 10 followers per leader on a good day, but other times, more than 3 followers cycle between connect, disconnect, reconnect in an unusable fashion.
I'm still trying to make usable, but wanted to document my success/failures so far in hopes that I can help many and perhaps get help from a few.
Any ideas would be welcomed and any tweaks will be tested and reported.