Objective C : 如何持续监听 stdin 上的传入数据?
Objective C : How to keep listening to incoming data on stdin?
我正在尝试使用 native messaging 从浏览器扩展中调用用 Objective C 编写的 MacOS 应用程序。
到目前为止,我已经想出了这段代码来处理使用 chrome.runtime.sendNativeMessage 发出的请求。
int main(int argc, char * argv[]) {
@autoreleasepool {
NSFileHandle *stdIn = [NSFileHandle fileHandleWithStandardInput];
NSError * stdinError = nil;
NSData * rawReqLen = [stdIn readDataUpToLength:4 error:&stdinError];
if(rawReqLen == nil || stdinError != nil) return 1;
NSUInteger reqLen;
[rawReqLen getBytes:&reqLen length:4];
NSData * req = [stdIn readDataUpToLength:reqLen error:&stdinError];
if(stdinError != nil) return 1;
handleRequest(req); // this does something depending on the received request
return 0;
}
}
这是有效的。
我需要帮助弄清楚如何使用 chrome.connectNative 来保持连接打开。具体来说,我的问题是让 MacOS 应用程序继续侦听传入消息,直到通过浏览器扩展程序调用 port.disconnect 关闭端口。
我已经试过这个代码,但它不起作用。
int main(int argc, char * argv[]) {
@autoreleasepool {
NSFileHandle *stdIn = [NSFileHandle fileHandleWithStandardInput];
[[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
object:stdIn
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
NSError * stdinError = nil;
NSData * rawReqLen = [stdIn readDataUpToLength:4 error:&stdinError];
if(rawReqLen == nil || stdinError != nil) exit(1);
NSUInteger reqLen;
[rawReqLen getBytes:&reqLen length:4];
NSData * req = [stdIn readDataUpToLength:reqLen error:&stdinError];
if(stdinError != nil) exit(1);
handleRequest(req);
}];
[stdIn waitForDataInBackgroundAndNotify];
}
}
有人知道如何实现吗?
解决方法是:
int main(int argc, char * argv[]) {
@autoreleasepool {
NSFileHandle *stdIn = [NSFileHandle fileHandleWithStandardInput];
[[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
object:stdIn
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
NSError * stdinError = nil;
NSData * rawReqLen = [stdIn readDataUpToLength:4 error:&stdinError];
if(rawReqLen == nil || stdinError != nil) exit(1);
uint32_t reqLen;
[rawReqLen getBytes:&reqLen length:4];
reqLen = OSSwapLittleToHostInt32(reqLen);
NSData * req = [stdIn readDataUpToLength:reqLen error:&stdinError];
if(stdinError != nil) exit(1);
handleRequest(req);
[stdIn waitForDataInBackgroundAndNotify];
}];
[stdIn waitForDataInBackgroundAndNotify];
}
NSRunLoop *loop = [NSRunLoop currentRunLoop];
[loop acceptInputForMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
[loop run];
return 0;
}
如果您想保持端口打开,也可以将调用 exit(1)
替换为对 [stdIn waitForDataInBackgroundAndNotify];
的新调用。
这可以很好地处理传入请求,但会破坏响应:写入 stdout 不再有效,我可能需要为每个响应停止 运行 循环并在完成后重新启动它。 (尚未测试)
我正在尝试使用 native messaging 从浏览器扩展中调用用 Objective C 编写的 MacOS 应用程序。
到目前为止,我已经想出了这段代码来处理使用 chrome.runtime.sendNativeMessage 发出的请求。
int main(int argc, char * argv[]) {
@autoreleasepool {
NSFileHandle *stdIn = [NSFileHandle fileHandleWithStandardInput];
NSError * stdinError = nil;
NSData * rawReqLen = [stdIn readDataUpToLength:4 error:&stdinError];
if(rawReqLen == nil || stdinError != nil) return 1;
NSUInteger reqLen;
[rawReqLen getBytes:&reqLen length:4];
NSData * req = [stdIn readDataUpToLength:reqLen error:&stdinError];
if(stdinError != nil) return 1;
handleRequest(req); // this does something depending on the received request
return 0;
}
}
这是有效的。
我需要帮助弄清楚如何使用 chrome.connectNative 来保持连接打开。具体来说,我的问题是让 MacOS 应用程序继续侦听传入消息,直到通过浏览器扩展程序调用 port.disconnect 关闭端口。
我已经试过这个代码,但它不起作用。
int main(int argc, char * argv[]) {
@autoreleasepool {
NSFileHandle *stdIn = [NSFileHandle fileHandleWithStandardInput];
[[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
object:stdIn
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
NSError * stdinError = nil;
NSData * rawReqLen = [stdIn readDataUpToLength:4 error:&stdinError];
if(rawReqLen == nil || stdinError != nil) exit(1);
NSUInteger reqLen;
[rawReqLen getBytes:&reqLen length:4];
NSData * req = [stdIn readDataUpToLength:reqLen error:&stdinError];
if(stdinError != nil) exit(1);
handleRequest(req);
}];
[stdIn waitForDataInBackgroundAndNotify];
}
}
有人知道如何实现吗?
解决方法是:
int main(int argc, char * argv[]) {
@autoreleasepool {
NSFileHandle *stdIn = [NSFileHandle fileHandleWithStandardInput];
[[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
object:stdIn
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
NSError * stdinError = nil;
NSData * rawReqLen = [stdIn readDataUpToLength:4 error:&stdinError];
if(rawReqLen == nil || stdinError != nil) exit(1);
uint32_t reqLen;
[rawReqLen getBytes:&reqLen length:4];
reqLen = OSSwapLittleToHostInt32(reqLen);
NSData * req = [stdIn readDataUpToLength:reqLen error:&stdinError];
if(stdinError != nil) exit(1);
handleRequest(req);
[stdIn waitForDataInBackgroundAndNotify];
}];
[stdIn waitForDataInBackgroundAndNotify];
}
NSRunLoop *loop = [NSRunLoop currentRunLoop];
[loop acceptInputForMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
[loop run];
return 0;
}
如果您想保持端口打开,也可以将调用 exit(1)
替换为对 [stdIn waitForDataInBackgroundAndNotify];
的新调用。
这可以很好地处理传入请求,但会破坏响应:写入 stdout 不再有效,我可能需要为每个响应停止 运行 循环并在完成后重新启动它。 (尚未测试)