Client/Server GKSessions

Solution 1:

You've hit the nail on the head:

Strangely enough, GK allows an "any to any" model.

This is a truly impressive achievement, technologically, by Apple

BUT !!! ........it is very important to realise that this is a very unusual option. In networking - for games - you almost always want a "normal" client-server model.

Over some 30 years, a huge amount of science has become established, regarding doing networking using a normal client-server "spoke" model. And indeed, for game programming, 99% of the time you definitely need, and want, a standard client-server "spoke" model.

This bears repeating:

(1) Apple created a highly unusual "peer to peer" mode when they made GK.

(2) That is technologically astounding, but,

(3) this novel P2P technology would not, actually, be used in very typical networking programming for games.

(4) Very confusingly: all the documentation talks about the P2P mode. This is confusing because: if you are new to networking programming, it would make you think that is "normal". In fact, it is very likely you will never use the P2P mode at all, when making real normal games.

To repeat!

If you are new to networking, when you see all the mentions of P2P mode in Apple's doco, it's important to realise that the (amazing) P2P feature is more of a novelty. In fact, for essentially all game networking, you will definitely need normal "everyday" client-server "spoke style" networking.

Just to ne crystal-clear .. it is much, much, much !! easier to do real-life networking using a normal client-server "spoke" model.

The P2P mode is "really clever" and you could definitely spend some time experimenting with it. For instance, it is fine for just "sending chat around" to every device connected.

But again (if you're a new networking programmer) you should realise it is rather a novelty. You will have to program using a normal, everyday, client-server model.

So ......................

given that you are going to program in a normal everyday client-server model.

Your first job becomes, strangely enough, "disabling" the P2P aspect!!!!!

This is easy enough if you know how. Here's precisely how to do it...

sessionMode:GKSessionModeServer .. on the server.
sessionMode:GKSessionModeClient ..  on the client.

So, for normal client-server programming, don't use GKSessionModePeer anywhere.

Secondly, don't forget in your clients, simply do not implement didReceiveConnectionRequestFromPeer:

Finally if all that doesn't work! In your clients, in peer:didChangeState:, you need to do this ...

// so this is in the CLIENT...
-(void)session:(GKSession *)session peer:(NSString *)peerID
                didChangeState:(GKPeerConnectionState)state
    {
    switch (state)
        {
        case GKPeerStateAvailable:
            // you have found the server!!
            // [session displayNameForPeer:peerID]
            self.theServerWeAreConnectedToPeerID = peerID;
            // you will definitely need to save that
            [session connectToPeer:theServerWeAreConnectedToPeerID
                withTimeout:0];
            break;

        case GKPeerStateConnected:
            // MAKE SURE it's our server
            // not just some bizarre peers, etc etc.
            if ( [theServerWeAreConnectedToPeerID isEqualToString:peerID] )
                {
                // you are connected - launch your tick or whatever
                }
            else
                {
                // completely ignore this!
                }
            break;

        case GKPeerStateDisconnected:
            if ( [theServerWeAreConnectedToPeerID isEqualToString:peerID] )
                {
                // you have been disconnected from the server!!
                }
            else
                {
                // weirdly this is telling you that one of your sister
                // clients, has been disconnected from the server. IGNORE
                }
            break;


        // GKPeerStateUnavailable .. likely not relevant
        case GKPeerStateUnavailable:
            // do nothing, ignore
            break;
        // from the modern doco..
        // "The delegate should ignore GKPeerStateConnecting changes
        // and implement the session:didReceiveConnectionRequestFromPeer:
        // method instead." .. blah blah .. for us that comment only
        // applies TO OUR SERVER, NOT here in the client.
        case GKPeerStateConnecting:
            // do nothing, ignore
            break;
        }
    }

Just to repeat. It is very likely you will want to NOT-use the P2P model: so, all of the above explains "how to DISABLE the P2P stuff."

Once again to repeat for absolute clarity:

GK (surpriginsly) contains a P2P mode. This is technologically amazing. You can, of course, use P2P mode for simple networking problems (notably chat-like problems). In practice, all the typical networking needs of any real game (whether an FPS, sports game, or whatever) must be done in ordinary client-server paradigm. (It would be staggeringly difficult to use P2P mode.)

Thus, it's necessary as a "first step" to know how to "not use" the P2P system in GK -- that is explained above in length.

(If you DO want to use the P2P system - you're all set, go for it !!)

GK is fantastic if you can figure out all the subtleties. With GK and ASIHttpRequest, you can basically do anything between computers at least in a basic way.

This question has hit the nail on the head ........ GK has a (highly unusual) P2P mode, and the documentation focusses on the P2P mode, which can be confusing to newcomers. Again P2P is incredibly clever, but as a rule you do not want the P2P mode. You want a normal clients-with-server spoke model, which is incedibly easier to program. Hope it helps!