截至2016年,Apple docs上的{{3}}陈旧且不起作用。例如,他们提到"保留",但在XCode 7.1中,默认是使用ARC,它不支持"保留"。我在网上尝试了各种各样的例子,但都没有。我如何在OSX上编写名为Distributed Objects的IPC机制,客户端应用程序可以在服务器应用程序上调用类方法(比如在LaunchDaemon中特别组成,但不是必需的)?
答案 0 :(得分:3)
这是一个让你前进的代码示例。 server.mm项目最好是将其加载到LaunchDaemon。我以root用户身份运行守护进程运行了一些测试,确定运行为“mike”的客户端应用程序将守护进程中的代码作为“root”运行。因此,它可以实现权限提升。请注意,此IPC不提供任何协议加密或身份验证挑战 - 因此,您可以自己添加它。您可以使用AES256 + Base64编码加密的密钥/列表,XML或JSON消息,以及发送和接收时长而严格的密码短语。请记住,在提升权限的情况下,建立一些保护机制非常重要。
首先启动服务器,它将坐在那里,等待连接。接下来启动客户端,它将建立连接,将数据传递给样本类方法,等待并接收消息,然后显示并关闭。服务器还将显示已发送连接以及在发送响应之前服务器上收到的内容。
请注意,这是一个同步示例,这意味着您调用类方法并等待响应。如果您希望它是异步的,那么您应该阅读oneway
keyword上的Apple文档。您将它放在类方法声明中的客户端和服务器中。请注意,oneway
关键字实际上最好只与返回void的类方法一起使用,因为您无法获得异步类方法的响应。因此,您将执行异步调用以启动任务,然后使用同步调用来获取您启动的任务的状态更新。所以,这是一个添加了oneway
关键字的类方法声明示例:
- (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;
}
#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;
}