【问题标题】:How Do I Do Distributed Objects on OSX with Objective C?如何使用 Objective C 在 OSX 上执行分布式对象?
【发布时间】:2016-07-21 22:25:43
【问题描述】:

截至 2016 年,Apple docs 已过时且不起作用。例如,他们提到“保留”,但在 XCode 7.1 中默认使用 ARC,它不支持“保留”。我在网上尝试了各种示例,但都没有奏效。如何在 OSX 上编写称为分布式对象的 IPC 机制,其中客户端应用程序可以调用服务器应用程序上的类方法(例如在 LaunchDaemon 中特别组合的方法,但不是必需的)?

【问题讨论】:

    标签: objective-c macos cocoa ipc distributed-objects


    【解决方案1】:

    这里有一个代码示例可以帮助您入门。 server.mm 项目最好将其加载到LaunchDaemon 中。我使用以 root 用户身份运行的守护进程运行了一些测试,果然,以“mike”身份运行的客户端应用程序以“root”身份运行守护进程中的代码。因此,它启用了特权提升。请注意,此 IPC 不提供任何协议加密或身份验证挑战 - 因此,由您自己添加。您可能可以逃脱使用 AES256 + Base64 编码加密的密钥/列表、XML 或 JSON 消息,并在发送和接收时使用长而强硬的密码短语。请记住,对于特权提升,您必须设置一些保护机制。

    首先启动服务器,它会坐在那里等待连接。接下来启动客户端,它将建立连接,将数据传递给示例类方法,等待并接收回消息,然后显示并关闭。服务器还将显示已建立连接以及在发送响应之前服务器上接收到的内容。

    请注意,这是一个同步示例,这意味着您调用类方法并等待响应。如果您希望它是异步的,那么您应该阅读oneway keyword 上的 Apple 文档。您将它放在类方法声明中的客户端和服务器中。请注意,oneway 关键字实际上只最好与返回 void 的类方法一起使用,因为您无法在异步类方法上获得响应。因此,您将执行异步调用来启动任务,然后使用同步调用来获取您启动的任务的状态更新。因此,这是一个添加了 oneway 关键字的类方法声明示例:

    - (oneway void)runTaskAsync:(NSString *)sParam;
    

    现在,代码...

    server.m

    #import <Foundation/Foundation.h>
    
    #define cat stringByAppendingString
    
    @interface MyService : NSObject {
        NSConnection *connection;
    }
    @end
    
    @implementation MyService 
    
    - (NSString *)testResponse:(NSString *)s {
        NSLog(@"...connection:%@", s);
        s = [s cat:@"-response"];
        return s;
    }
    
    - (void)runService {
        connection = [[NSConnection alloc] init];
        [connection setRootObject:self];
        [connection registerName:@"com.acme.myservice"];
        [[NSRunLoop currentRunLoop] run];
    }
    
    @end
    
    int main (int argc, const char *argv[]) {
        @autoreleasepool {
            NSLog(@"ACME MyService 1.0\n");
            MyService *svc = [[MyService alloc] init];
            [svc runService];
        }
        return 0;
    }
    

    client.m

    #import <Foundation/Foundation.h>
    
    int main (int argc, const char *argv[]) {
        @autoreleasepool {
            NSLog(@"building proxy object");
            id proxy = [NSConnection rootProxyForConnectionWithRegisteredName:@"com.acme.myservice" host:nil];
            NSLog(@"calling test response thru proxy object");
            NSString *sResult = [proxy testResponse:@"sent"];
            NSLog(@"RESULT=%@", sResult);
        }
        return 0;
    }
    

    【讨论】:

    • 这不需要是 Objective-C++,据我所知它没有使用 C++ 的任何特性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 2011-04-29
    • 2012-03-05
    相关资源
    最近更新 更多