I am trying to create a connection between two applications on the same computer with a NSSocketPort
, but it only seems to be working one way.
I have a server that creates a NSMutableDictionary
and sets it as the rootObject
. The client reads the rootProxy
and gets the dictionary as the server created it. But then I want the client to add an additional key/value set to the dictionary and set the dictionary as the rootObject
again. But the server does not seem to receive the last value/key set after the client has set it.
Server:
self.portRecv = [[NSSocketPort alloc] initWithTCPPort:30028];
self.conn = [NSConnection connectionWithReceivePort:self.portRecv sendPort:nil];
self.data = [NSMutableDictionary dictionary];
[self.data setObject:@"Value" forKey:@"serverSet"];
self.conn.rootObject = self.data;
self.conn.delegate = self;
This is how the server reads the value:
self.data = (NSMutableDictionary*)[self.conn rootProxy];
Client:
self.portSend = [[NSSocketPort alloc] initRemoteWithTCPPort:30028 host:@"127.0.0.1"];
self.conn = [NSConnection connectionWithReceivePort:nil sendPort:self.portSend];
self.conn.delegate = self;
self.data = (NSMutableDictionary*)[self.conn rootProxy];
[self.data setObject:@"Value" forKey:@"clientSet"];
self.conn.rootObject = self.data;
The client's self.data
receives the "serverSet : Value"
just fine, but when I let the server read the [self.conn rootProxy]
after the client has set the "clientSet : Value"
the server gets a dictionary with the serverSet
value and not the clientSet
.
I am answering the delegate messages as below:
- (BOOL)makeNewConnection:(NSConnection *)conn sender:(NSConnection *)ancestor
{
return YES;
}
- (BOOL)connection:(NSConnection *)ancestor shouldMakeNewConnection:(NSConnection *)conn
{
return YES;
}
- (BOOL)connection:(NSConnection *)conn handleRequest:(NSDistantObjectRequest *)doReq
{
NSInvocation *invocation = [doReq invocation];
[invocation invoke];
if ([invocation selector] == @selector(entitiesByName))
{
id retVal;
[invocation getReturnValue:&retVal];
NSDictionary *rebuilt = [NSDictionary dictionaryWithDictionary:retVal];
[invocation setReturnValue:&rebuilt];
}
[doReq replyWithException:nil];
return YES;
}
Shouldn't I be able to add a value and return the rootObject
to the server? How can I do that?
I managed to solve this by implementing a class that implements the NSCoding
protocol and then use this as the rootObject
. By doing that I was able to invoke different methods on the server's object from the client.
It ended up like this:
Server:
int port = 30012;
self.socketModel = [[SocketModel alloc] init];
self.socketModel.statusBarUiDelegate = self;
NSSocketPort* recvPort = [[NSSocketPort alloc] initWithTCPPort:port];
self.conn = [NSConnection connectionWithReceivePort:recvPort sendPort:nil];
[self.conn setRootObject:self.socketModel];
SocketModel:
@interface SocketModel : NSObject<NSCoding>
-(NSString*)performTask:(NSString*)data;
-(void)taskCompleted;
@end
Client:
NSString* data = @"pewpew";
NSSocketPort* recv = [[NSSocketPort alloc] initRemoteWithTCPPort:30012 host:@"127.0.0.1"];
self.conn = [NSConnection connectionWithReceivePort:nil sendPort:recv];
[self.conn setRequestTimeout:5];
NSString* result = nil;
SocketModel* obj = nil;
obj = (SocketModel*)[self.conn rootProxy];
result = [builderObj performTask:data];
[obj taskCompleted];
I was even able to create a delegate on my SocketModel
and assign it to my client, which made the server provide progress info to the client.