views:

240

answers:

2

Hi,

I'm a fairly novice obj-c developer and have a question on how to set up a client-server relationship. I'm designing (mostly as a hobby) a board game to be played over the internet with friends and family (think monopoly). My problem: how do I set up the appropriate client-server relationship to have one server with multiple clients?

My thinking was to have one server contain all the information on the state of the game as well as send appropriate messages to a variety of objects through Cocoa's excellent distributed objects framework. However, I can't figure out how to have one server accept multiple clients.

firstConnection = [NSConnection defaultConnection];
[firstConnection setRootObject: firstPlayer];
[[NSRunLoop currentRunLoop] run];

But then what? Is there a way to tell the run loop to stop when a client is attached? I'd like to avoid multiple threading if possible as that would be a whole new complication to learn and this project is already challenging enough!

Any help would be greatly appreciated and I'd be happy to clarify anything at all if necessary.

Thanks in advance.

+2  A: 

Basically the strategy to take is to have the server register itself as the root object. When the client connects to the server, it sends the server a connection message (defined by the server's protocol you create) that allows the server to register that client in order to send messages to it in the future. This could be as simple as adding the client to an array; no special run loops or threads should be needed.

Here's a quick example to communicate across processes, from a test app I wrote back when I was learning DO for the first time. Once the setup is done you can add code to make the server send messages to one or more objects in the _clients array based on any event you'd like, including setting up a timer for a rough game loop.

Server:

- (void)registerClient:(byref Client *)client;
{
    [_clients addObject:client];
}

- (void)awakeFromNib;
{
    _clients = [[NSMutableArray alloc] init];

    [[NSConnection defaultConnection] setRootObject:self];

    if ( [[NSConnection defaultConnection] registerName:@"server"] == NO ) 
    {
     // error code!
    }
}

Client:

- (void)awakeFromNib;
{       
    id theProxy;
    theProxy = [[NSConnection rootProxyForConnectionWithRegisteredName:@"server" host:nil] retain];
    [theProxy setProtocolForProxy:@protocol(ServerP)];

    if ( theProxy == nil )
     // error code!

    [theProxy registerClient:self];
}

Keep in mind that there are a lot of "gotchas" in distributed objects! Start simple, even if it means developing a rough prototype of your game idea first.

Marc Charbonneau
+1 for the great exampleMarc, one thing I'm unclear on is the line "[theProxy registerClient:self]". How can the server call on the registered client in the future since "self" is only a pointer to the client and not a proxy? Is the "Client" object a subclass of NSDistantObject?
manifest
A: 

Cocoa's excellent distributed objects framework

That's the first time I've seen those words together like that ;)

jon hohle
It's pretty excellent.
arbales