在objc中,我们可以很简单的通过分布式对象实现线程与线程,进程与进程,以及机器与机器之间进行对象的交互:Portable Distributed Objects。 你可以通过"vend" 服务器发布分布式对象访问接口, 从而达到"vend"对象到远程接口。
"vend": 叫卖,“vend” 服务器有点像一个卖场,任何商家都可以通过注册入场将自己的产品进行销售, 并且这个卖场基于三种类型:1) 卖物理产品(NSMachBootstrapServer),这种产品只许内部销售,通过提供的产品使用其功能。2)卖服务(NSMessagePortNameServer),不提供物理产品,用户通过叫服务的方式使用产品功能,同1)一样,只允许内部销售。3)远程物理产品(NSSocketPortNameServer), 这种产品可以与其它卖场进行销售。
与之对应的产品或渠道有:1) NSMachPort. 2) NSMessagePort. 3) NSSocketPort.
由上我们可以这样理解"vend"服务端,它通过名称向系统注册服务类型,1) 和 2)只能在本地机器使用,即线程或进程间使用, 1) 提供的是注册时所对应的对象,远程客户端像使用本地对象一样使用该项对象。2) 提供的是基于消息的服务,不提供远程访问对象。 3) 提供机器与机器间的对象访问,基于socket的网络编程。
下面我们先看几个例子:
HelloPDOClient.h#import <Foundation/Foundation.h>
@interface HelloPDOClient:NSObject
{
id serverObject;
}
- (void) connect;
- (void)log:(NSString*)string;
@endHelloPDOClient.m#import "HelloPDOClient.h"
@implementation HelloPDOClient
- (void) connect
{
serverObject=[NSConnection rootProxyForConnectionWithRegisteredName:@"MyServer" host: nil];
}
- (void)log: (NSString*)string
{
[serverObject log: string];
}
@endClient.m#import "HelloPDOClient.h"
main()
{
NSAutoreleasePool* pool=[[NSAutoreleasePool alloc] init];
Client* client=[[Client alloc] init];
[client connect];
[client log:@"Hello, world!"];
[pool release];
}HelloPDOServer.h#import <Foundation/Foundation.h>
@interface HelloPDOServer:NSObject
{
NSConnection * serverConnection;
}
- (void)log:(NSString*)string;
- (void)serve;
- NSConnection createConnectionName:(NSString*)name;
@endHelloPDOServer.m#import "HelloPDOServer.h"
@implementation HelloPDOServer
- (void)log: (NSString*)string
{
NSLog (string);
}
- (void)serve
{
serverConnection=[self createConnectionName:@"MyServer"];
[[NSRunLoop currentRunLoop] run];
}
- (NSConnection*) createConnectionName:(NSString*)name
{
NSConnection* newConnection=[[NSConnection alloc] init];
if ([newConnection registerName:name])
{
[newConnection setRootObject:self];
}
else
{
[newConnection release];
newConnection=nil;
}
return newConnection;}
@endServer.m#import "HelloPDOServer.h"
main()
{
NSAutoreleasePool* pool=[[NSAutoreleasePool alloc] init];
Server* server=[[Server alloc] init];
[server serve];
[pool release];
}
好,上面是一个最简单的分布式对象访问程序,在两个进程中共享对象,了解了这一点,我们现在开始对上面程序进行改变,使用NSPort的派生类NSMachPort和NSSocketPort.
1) 服务端
a. NSMachPort
NSPort *receivePort = [[NSMachPort alloc] init]; b. NSSocketPort
NSPort *receivePort = [[NSSocketPort alloc] initWithTCPPort:8080];然后修改NSConnection, 使其使用NSPort。
NSConnection *conn = [[NSConnection alloc] initWithReceivePort:receivePort
sendPort:nil];
使用NSMachPort或NSMessagePort都需要在本地注册服务名称,即调用NSConnection对象的registerName:, 而NSSocketPort由于是远程tcp访问,所以不需要注册本地服务名。
NSConnection将NSPort自动加入到RunLoop(消息队列, 下章将讲解)中,从而监控客户端的调用
最后,启用NSRunLoop.
[[NSRunLoop currentRunLoop] run];
2) 客户端
a. NSMachPort
NSPort *sendPort = [[NSMachBootstrapServer sharedInstance] portForName:@"MyServer" host:nil];b. NSSocketPort
NSPort *sendPort = [[NSSocketPort alloc] initRemoteWithTCPPort:8080 host:@"serverHostName"];下面通过NSConnection连接服务器:
NS_DURING
NSConnection* conn = [[NSConnection alloc] initWithReceivePort:(NSPort*)[[sendPort class] port] sendPort:sendPort];
id proxyObj = [conn rootProxy];
NS_HANDLER
proxyObj = nil;
NS_ENDHANDLER这样就可以直接使用proxyObj了。 由上我们不难理解,NSPort就是底层通信通道,它有三种类型的通信通道,分别是NSMachPort, NSMessagePort, 和NSSocketPort.
1246

被折叠的 条评论
为什么被折叠?



