Question

I would like to use NSConnection/NSDistributedObject for interprocess communication. I would like the client to be able to handle the case where the server is only occasionally reachable.

How can I determine if sending a message to the NSConnection will fail or has failed? Currently if my server (the process that has vended the remote object) dies, the client will crash if it sends a selector to the remote object.

Ideally I'd like to have a wrapper for the remote object that can lazily instantiate (or reinstantiate) the connection, and return a default value in the case where the connection could not be instantiated, or the connection has failed. I don't really know the correct way to do this using objective c.

Here's some pseudocode representing this logic:

if myConnection is null:
    instantiate myConnection
    if MyConnection is null:
        return defaultValue

    try
        return [myConnection someMethod]
    catch
        myConnection = null
        return defaultValue
Was it helpful?

Solution

Unfortunately the only way to detect a connection failure is to use an exception handler, as there is no reliable way to "ask" a remote object if the connection is still valid. Thankfully, this is simple:

//get the distributed object
id <YourDOProtocol> remoteObject = (id <YourDOProtocol>)[NSConnection rootProxyForConnectionWithRegisteredName:@"YourRegisteredName" host:yourHost];

//call a method on the distributed object
@try
{
    NSString* response = [remoteObject responseMethod];
    //do something with response
}
@catch(NSException* e)
{
    //the receiver is invalid, which occurs if the connection cannot be made
    //handle error here
}

OTHER TIPS

If your server is quiting gracefully then, I'm of the understanding, that it'll post an NSConnectionDidDieNotification as it's connection closes so you could register your client like this:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connectionDidDie:) name:NSConnectionDidDieNotification object:remoteObject];

Perhaps your connectionDidDie:method could set a Boolean var that you can check prior to attempting sending the message.

Your DO could post a notification to say that it's started (although I think there are also system messages for that but I've only just started learning about DO's) and you could similarly register to be notified of it's startup.

I guess Rob's answer is a definite 'catch-all' and you wouldn't need to worry about the notification centre having not got through to the server in time.

I've been using the 'did die' notification it in my first DO app and I hope it helps you.

Todd.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top