Cocoa 分布式对象

Posted

技术标签:

【中文标题】Cocoa 分布式对象【英文标题】:Cocoa Distributed Objects 【发布时间】:2009-11-19 17:39:17 【问题描述】:

试图弄清楚如何运行这个分布式对象演示让我很头疼。我可以在同一台机器上本地运行它。

情况是这样的。我有一个服务器应用程序,它在远程计算机上生成一个客户端应用程序 [使用 OpenGLView]。

我可以使用 AppleScript 轻松做到这一点。

客户端应用程序似乎可以出售它的 OpenGLView 窗口:

clientPort = [[NSSocketPort alloc] initWithTCPPort:SERVER_PORT];
if(clientPort == nil) continue; else NSLog(@"Port OK");

clientConnection = [NSConnection connectionWithReceivePort:clientPort sendPort:nil];
if(clientConnection == nil) continue; else NSLog(@"Conn OK");

[[NSSocketPortNameServer sharedInstance] registerPort:clientPort name:@"DOTest3_0"];

//Vend Object
@try 
[clientConnection setRootObject:object];
NSLog([NSString stringWithFormat:@"Port %d: Vend OK", (SERVER_PORT + i)]);
return;
 @catch (...) 
NSLog([NSString stringWithFormat:@"Port %d: Vend Next", (SERVER_PORT + i)]);

服务器应用程序找到端口和连接,但引发超时异常:

// Create temporary Pointer to kGLView Object.
  id <NSCoding, kGLViewProtocol> openGLView;

      // Setup Port, Connection, & Proxy
      portTest = (NSSocketPort *)[[NSSocketPortNameServer sharedInstance] portForName:@"DOTest3_0" host:@"*"];
      if (portTest == nil ) continue ; else NSLog(@"Port OK");

      connTest = [NSConnection  connectionWithReceivePort:nil sendPort:portTest];
      if (connTest == nil ) continue ; else NSLog(@"Conn OK");

      openGLView = [[connTest rootProxy] retain];
      if (openGLView == nil ) continue ; else NSLog(@"OpenGL OK");

      [openGLView drawWithRotation: rotationAngle];

  

而我终其一生都无法弄清楚为什么。

我进入客户端 PC 的控制台: “端口正常” “康好” “端口 8081:售货正常”

我进入服务器 PC 的控制台: “端口正常” “康好” 2009 年 11 月 18 日下午 2:05:36 DOTest3[15278] [NSPortCoder sendBeforeTime:sendReplyPort:] 超时 (10280263936.092180 280263936.092642) 1

即使 TimeOuts 都设置为 60 秒。

救命!

-斯蒂芬


服务器:MacMini OS X 10.5 客户端:MacPro OS X 10.6 远程登录、管理等都开启了。


编辑: 听从 NSResponder 的建议,我已经卖掉了 Controller,但还是不行。

客户/供应商:

-(void)vend:(id)object 
  port = [[[NSSocketPort alloc] initWithTCPPort:[self tcpPort]] 
          retain];

  conn = [[NSConnection connectionWithReceivePort:port sendPort:nil] 
          retain];

  for (int i = 0; i < 10; i++) 
    [[NSSocketPortNameServer sharedInstance] registerPort:port
                                                     name:[[self portName] stringByAppendingFormat:@"_%d", i]];
    @try 
      [conn setRootObject:object];
      return;
     @catch (...) 
      NSLog(@"Vend Next");
      continue;
    
  
  NSLog(@"Vend Failed");

客户端控制器:

-(id)init 
  self = [super init];

  [self setRotationAngle:0.0f];

  clientObj = [[Client alloc] initWithName:@"DOTest4" 
                                   Address:@"10.10.5.104" // mini
                                      Port:48557];

  [clientObj vend:self];

  return self;

服务器控制器:

-(IBAction)rotateClient:(id)sender 
  NSArray *vendedObjects = [serverObj getVendedObjects];
  id <NSCoding, ClientController_Protocol> proxy;

  if (vendedObjects != nil) 
    for (int i = 0; i < [vendedObjects count]; i++) 
      proxy = [vendedObjects objectAtIndex:i];
      [proxy rotate];
    
  
    // release
  [vendedObjects release];

服务器/(抓取出售的对象)

-(NSArray *)getVendedObjects 

  NSArray *vendedObjects = [[[NSArray alloc] init] retain];
  NSSocketPort *port;
  NSConnection *conn;

  for (int i = 0; i< 10; i++) 
    // Get Port Object
    port = (NSSocketPort *)[[NSSocketPortNameServer sharedInstance] 
                           portForName:[[self portName] stringByAppendingFormat:@"_%d", i]
                           host:[self addressRemote]];
    if (port == nil) continue;
    // Create Connection with Timeouts
    conn = [NSConnection connectionWithReceivePort:nil sendPort:port];
    if (conn == nil) continue;

    [conn setReplyTimeout:(NSTimeInterval)60.0];
    [conn setRequestTimeout:(NSTimeInterval)60.0];

    // Get VendedObject of Connection
    vendedObjects = [[vendedObjects arrayByAddingObject:[conn rootProxy]] retain];
  

  return vendedObjects;

叹息...我确定我只是在这里忽略了一些真正可可基础的东西。

-S!

【问题讨论】:

叹息……这行得通。我的问题是返回 NSDistance 对象的 NSArray。某处有东西被释放了。在“getVendedObjects”方法中执行“旋转”命令效果很好! -S 【参考方案1】:

我从未见过有人试图通过 DO 链接出售视图或窗口,我很惊讶它甚至在本地主机上也能正常工作。每当我使用 DO 时,它都是从服务器控制器层中的对象到客户端中相应的控制器。

【讨论】:

啊,那可能是我的问题。在代码中而不是在 IB 中拥有对象不是控制器吗? 我完全被这条评论弄糊涂了。您应该可以出售任何物品吧!?我还没有尝试过,但将来会尝试。谢谢 您可以很好地出售视图或窗口。问题是它们不会绘制到通过分布式对象传递的对象中——它们绘制到图形上下文中,并且始终是出售对象的进程的图形上下文。 (这甚至可以用 NSImage 咬你——确保你传递了那些 bycopy。)所以你可以在 DO 中出售一个视图,你甚至可以有效地更改它的属性,但你不能将它绘制到另一个应用程序中。跨度>

以上是关于Cocoa 分布式对象的主要内容,如果未能解决你的问题,请参考以下文章

Cocoa/Objective-C 和分布式对象的例子?

Cocoa 中的分布式对象

Cocoa 分布式对象、GC 客户端、非 GC 服务器

在可可中实现分布式对象

研学社•架构组 | CoCoA:大规模机器学习的分布式优化通用框架

可可分布式对象中的双向通信