现在的位置: 首页 > 综合 > 正文

(4)iPhone开发基础 - 分布式对象

2014年10月26日 ⁄ 综合 ⁄ 共 3042字 ⁄ 字号 评论关闭

在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;
@end

HelloPDOClient.m

#import "HelloPDOClient.h"

@implementation HelloPDOClient
- (void) connect
{
   serverObject=[NSConnection rootProxyForConnectionWithRegisteredName:@"MyServer" host: nil];
}
- (void)log: (NSString*)string
{
         [serverObject log: string];
}

@end

Client.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;
@end

HelloPDOServer.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;}
@end

Server.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.

抱歉!评论已关闭.