如何在 OSX 上使用 Objective C 执行分布式对象?
How Do I Do Distributed Objects on OSX with Objective C?
截至 2016 年,Apple docs 已过时且无法使用。例如,他们提到 "retain",但在 XCode 7.1 中默认使用 ARC,它不支持 "retain"。我在网上尝试了各种示例,none 成功了。我如何在 OSX 上编写称为分布式对象的 IPC 机制,其中客户端应用程序可以调用服务器应用程序上的 class 方法(就像一个特别由 LaunchDaemon 组成的方法,但不是必需的)?
这里有一个代码示例可以帮助您开始。 server.mm 项目最好将其加载到 LaunchDaemon 中。我 运行 以 root 用户身份使用守护程序 运行 进行了一些测试,果然客户端应用程序是 运行 作为 "mike",运行 中的代码守护进程为 "root"。因此,它启用特权提升。请注意,此 IPC 不提供任何协议加密或身份验证挑战——因此,由您自己添加。您可能可以通过使用 AES256 + Base64 编码加密的 key/list、XML 或 JSON 消息,在发送和接收时使用长而难的密码短语。请记住,通过特权提升,设置一些保护机制非常重要。
首先启动服务器,它会坐在那里等待连接。接下来启动客户端,它将建立连接,将数据传递给示例 class 方法,等待并接收返回的消息,然后显示并关闭。服务器还将显示已建立连接以及在发送响应之前服务器上收到的内容。
请注意,这是一个同步示例,这意味着您调用 class 方法并等待响应。如果您希望它是异步的,那么您应该阅读 oneway
keyword 上的 Apple 文档。您将它放在 class 方法声明中的客户端和服务器中。请注意,oneway
关键字实际上只最好与 returns 无效的 class 方法一起使用,因为您无法在异步 class 方法上获得响应。因此,您将执行异步调用来启动任务,然后使用同步调用来获取您启动的任务的状态更新。因此,这是一个 class 方法声明的示例,该方法声明将添加 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;
}
截至 2016 年,Apple docs 已过时且无法使用。例如,他们提到 "retain",但在 XCode 7.1 中默认使用 ARC,它不支持 "retain"。我在网上尝试了各种示例,none 成功了。我如何在 OSX 上编写称为分布式对象的 IPC 机制,其中客户端应用程序可以调用服务器应用程序上的 class 方法(就像一个特别由 LaunchDaemon 组成的方法,但不是必需的)?
这里有一个代码示例可以帮助您开始。 server.mm 项目最好将其加载到 LaunchDaemon 中。我 运行 以 root 用户身份使用守护程序 运行 进行了一些测试,果然客户端应用程序是 运行 作为 "mike",运行 中的代码守护进程为 "root"。因此,它启用特权提升。请注意,此 IPC 不提供任何协议加密或身份验证挑战——因此,由您自己添加。您可能可以通过使用 AES256 + Base64 编码加密的 key/list、XML 或 JSON 消息,在发送和接收时使用长而难的密码短语。请记住,通过特权提升,设置一些保护机制非常重要。
首先启动服务器,它会坐在那里等待连接。接下来启动客户端,它将建立连接,将数据传递给示例 class 方法,等待并接收返回的消息,然后显示并关闭。服务器还将显示已建立连接以及在发送响应之前服务器上收到的内容。
请注意,这是一个同步示例,这意味着您调用 class 方法并等待响应。如果您希望它是异步的,那么您应该阅读 oneway
keyword 上的 Apple 文档。您将它放在 class 方法声明中的客户端和服务器中。请注意,oneway
关键字实际上只最好与 returns 无效的 class 方法一起使用,因为您无法在异步 class 方法上获得响应。因此,您将执行异步调用来启动任务,然后使用同步调用来获取您启动的任务的状态更新。因此,这是一个 class 方法声明的示例,该方法声明将添加 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;
}