Thursday, January 27, 2011

Distributed Objects on OS X

I got a simple example with Distributed Objects working. This is supposed to be the standard way to communicate between processes. I tried it first with both the Server and the Client in PyObjC. Eventually I rewrote the Server in Objective-C and then it worked.

[UPDATE: Found a great working example (old, but from an Apple engineer here). ]

The output is:


> python listen.py 
<VendedObject: 0x10010cce0>
<objective-c class NSDistantObject at 0x7fff70a64868>
woof


I'm not sure what the problem was but the error I got was


[OC_PythonString initWithBytes:length:encoding:]: unrecognized selector sent to instance 0x3635130


Server:


// gcc talk.m -o test -framework Foundation
#import <Foundation/Foundation.h>

@interface VendedObject:NSObject {}
-(NSString *) speak;
@end

@implementation VendedObject

-(NSString *) speak {
return @"woof";
}
@end

int main(){
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
VendedObject *obj;
obj = [[[VendedObject alloc ] init] autorelease];
NSLog(@"%@", [obj description]);

NSConnection *conn;
conn = [[[NSConnection alloc] init] autorelease];
[conn setRootObject:obj];
BOOL result;
result = [conn registerName:@"my_server"];
if (!result) {
NSLog(@"Failed to register Name");
}
else {
NSLog(@"%@", [conn description]);
}
[[NSRunLoop mainRunLoop] run];
[pool drain];
return 0;
}


Run with:


> ./test
2011-01-27 12:09:39.001 test[36995:903] <VendedObject: 0x10010cce0>
2011-01-27 12:09:39.005 test[36995:903] (** NSConnection 0x100112050 receivePort <NSMachPort: 0x100112530> sendPort <NSMachPort: 0x100112530> refCount 1 **)


You'll have to kill the process when you're done. If you have tried once already in Terminal, you will need to Quit Terminal and Re-launch. Otherwise registerName: will fail.

Client:


from Foundation import *

proxy_obj = NSConnection.rootProxyForConnectionWithRegisteredName_host_(
#"my_server", "osxserver.local")
"my_server", None)
if not proxy_obj:
print 'Did not get an object from the server.'
else:
print proxy_obj.description()
print type(proxy_obj)
print proxy_obj.speak()


I also tried to connect to another machine on my local network, but I couldn't get that to work either. The proxy_obj was nil/None.