如何在OSX上使用目标C做分布式对象? [英] How Do I Do Distributed Objects on OSX with Objective C?

查看:109
本文介绍了如何在OSX上使用目标C做分布式对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自2016年起, Apple docs 在这是陈旧的,不工作。例如,他们提到保留,但在XCode 7.1,默认是使用ARC,它不支持保留。我在网上尝试了各种例子,没有工作。我如何编写在OSX上称为分布式对象的IPC机制,其中客户端应用程序可以在服务器应用程序上调用类方法(类似于一个特别由LaunchDaemon组成,但不是必需的)?

As of 2016, the Apple docs on this are stale and don't work. For instance, they mention "retain", but in XCode 7.1 the default is to use ARC and it doesn't support "retain". I tried various examples on the web and none worked. How do I code the IPC mechanism called Distributed Objects on OSX, where a client application can call class methods on a server application (like one especially composed in a LaunchDaemon, but not required)?

推荐答案

这里是一个代码示例,让你去。 server.mm项目最好是将其加载到 LaunchDaemon 中。我使用以root用户身份运行的守护程序运行了一些测试,确保足够的客户端应用程序(以mike运行)将守护程序中的代码作为root运行。因此,它启用特权提升。请注意,此IPC不提供任何协议加密或身份验证挑战 - 因此,您需要自己添加。您可以使用AES256 + Base64编码加密的密钥/列表,XML或JSON消息,在发送和接收时使用冗长,难用的密码短语。记住,对于特权提升,非常重要的一点是你应该设置一些保护机制。

Here's a code sample to get you going. The server.mm project is probably best that you load it into a LaunchDaemon. I ran some tests with the daemon running as root user, and sure enough the client application, which was running as "mike", ran the code in the daemon as "root". So, it enables privilege elevation. Note that this IPC doesn't provide any protocol encryption or authentication challenges -- so, it's up to you to add that yourself. You can probably get away with a key/list, XML, or JSON message that's encrypted with AES256 + Base64 encoding with a long, tough password phrase both on sending and receiving. Remember, with privilege elevation, it's very important that you put some protection mechanisms in place.

首先启动服务器,它会坐在那里,等待连接。接下来启动客户端,它将建立连接,将数据传递给示例类方法,等待并接收消息,然后显示它并关闭。

Launch the server first and it will sit there, waiting on connections. Launch the client next and it will establish a connection, pass data to a sample class method, wait and receive a message back, and then display it and shut down. The server will also show the connection was made and what was received on the server before a response back was sent.

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

Note that this is a synchronous example, meaning you call the class method and it waits for a response. If you want it to be asynchronous, then you should read the Apple documentation on the oneway keyword. You put it in both the client and server in the class method declaration. Just note that the oneway keyword is really only best used with a class method that returns void because you can't get a response back on an asynchronous class method. So, you'd do an async call to start a task, and then use a synchronous call to get a status update on that task you started. So, here's an example of a class method declaration that would have the oneway keyword added:

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

现在,代码...

#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



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;
}

这篇关于如何在OSX上使用目标C做分布式对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆