سؤال

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top