For Mac OSX, I'm trying to use an NSConnection to proxy access of an object from one application instance to another on the same host. The relevant code is below. I can provide more if needed. Assume when I say "server", I'm referring to the application that actually "vends" an object with an NSConnection. And "client" is the other instance of the same application that gets a proxy to it.
Everything works, except for two issues.
When an application acting as a server attempts to tear down the object it is vending, any client connected through a proxy still remains. That is, even after I call my
stopLocalServer
function below, any client app that previously connected and got a proxy object is still able to send messages and invoke code on the server app. I would have expected the client to throw an exception when passing a message after the server callsNSConnection:invalidate
. How do I forcibly disconnect any client without requiring the server process to exit?In the
startClientConnection
code below, if the server never vended the object in the first place with the expected registered name, then the call on the client toNSConnection:connectionWithRegisteredName:host
will immediately return nil. This is good. But if the server had started vending an object via thestartLocalServer
code below, then later stops vending it withstopLocalServer
, subsequent client attempts to connect will hang (block forever) until the server application process exits. The call to NSConnection:connectionWithRegisteredName returns a non-nil object, but the call to[_clientConnection rootProxy]
hangs forever until the server application actually exits.
I suspect that I'm not properly tearing down the original NSConnection object or I'm missing something basic here.
Here is some relevant code for the platform that my user interface code sits on top of:
-(void)startLocalServer:(NSString*)str
{
[self stopLocalServer]; // clean up any previous instance that might be running
_serverConnection = [NSConnection new];
[_serverConnection setRootObject:self];
[_serverConnection registerName:str];
}
-(void)stopLocalServer
{
[_serverConnection registerName:nil];
[_serverConnection setRootObject:nil];
[_serverConnection invalidate];
_serverConnection = nil;
}
-(void)startClientConnection:(NSString*)str
{
[self stopClientConnection]; // tear down any previous connection
_clientConnection = [NSConnection connectionWithRegisteredName:str host:nil];
if ((_clientConnection == nil) || (_clientConnection.valid == NO))
{
LogEvent(@"ERROR - _clientConnection is nil or invalid!");
}
else
{
_proxy = [_clientConnection rootProxy];
}
}
-(void)stopClientConnection
{
_proxy = nil;
[_clientConnection invalidate];
_clientConnection = nil;
}