问题描述
我正在考虑在 Mac 上构建一个带有后端守护进程的 Cocoa 应用程序(可能实际上只是一个主要无头的 Cocoa 应用程序),以及 0 个或多个在本地运行的客户端"应用程序(尽管如果可能的话我也想支持远程客户端;远程客户端只能是其他 Mac 或 iPhone 操作系统设备).
I'm looking at building a Cocoa application on the Mac with a back-end daemon process (really just a mostly-headless Cocoa app, probably), along with 0 or more "client" applications running locally (although if possible I'd like to support remote clients as well; the remote clients would only ever be other Macs or iPhone OS devices).
所传达的数据将是相当微不足道的,主要只是文本和命令(我想无论如何都可以表示为文本),也许偶尔会有小文件(可能是图像).
The data being communicated will be fairly trivial, mostly just text and commands (which I guess can be represented as text anyway), and maybe the occasional small file (an image possibly).
我已经研究了几种执行此操作的方法,但我不确定哪种方法最适合手头的任务.我考虑过的事情:
I've looked at a few methods for doing this but I'm not sure which is "best" for the task at hand. Things I've considered:
- 读取和写入文件(...是的),非常基本但不是很可扩展.
- 纯套接字(我没有使用套接字的经验,但我似乎认为我可以使用它们在本地和通过网络发送数据.虽然如果在 Cocoa 中做所有事情似乎很麻烦
- 分布式对象:对于这样的任务来说似乎不太优雅
NSConnection
:我真的不知道这个类到底做了什么,但我在一些 IPC 搜索结果中读到了它
- Reading and writing to a file (…yes), very basic but not very scalable.
- Pure sockets (I have no experience with sockets but I seem to think I can use them to send data locally and over a network. Though it seems cumbersome if doing everything in Cocoa
- Distributed Objects: seems rather inelegant for a task like this
NSConnection
: I can't really figure out what this class even does, but I've read of it in some IPC search results
我确定我遗漏了一些东西,但我很惊讶地发现缺乏关于这个主题的资源.
I'm sure there are things I'm missing, but I was surprised to find a lack of resources on this topic.
推荐答案
我目前正在研究相同的问题.对我来说,以后添加 Windows 客户端的可能性使情况变得更加复杂;就您而言,答案似乎更简单.
I am currently looking into the same questions. For me the possibility of adding Windows clients later makes the situation more complicated; in your case the answer seems to be simpler.
关于您考虑过的选项:
控制文件:虽然可以通过控制文件进行通信,但您必须记住,文件需要通过网络文件系统在所涉及的机器之间进行通信.因此,网络文件系统充当了实际网络基础设施的抽象,但并没有提供网络通常具有的全部功能和灵活性.实现: 实际上,每对客户端/服务器至少需要两个文件:服务器用于向客户端发送请求的文件和用于响应的文件.如果每个进程都可以双向通信,则需要重复此操作.此外,客户端和服务器都在拉"的基础上工作,即他们需要经常重新访问控制文件,看看是否有新的东西已经交付.
Control files: While it is possible to communicate via control files, you have to keep in mind that the files need to be communicated via a network file system among the machines involved. So the network file system serves as an abstraction of the actual network infrastructure, but does not offer the full power and flexibility the network normally has. Implementation: Practically, you will need to have at least two files for each pair of client/servers: a file the server uses to send a request to the client(s) and a file for the responses. If each process can communicate both ways, you need to duplicate this. Furthermore, both the client(s) and the server(s) work on a "pull" basis, i.e., they need to revisit the control files frequently and see if something new has been delivered.
该解决方案的优势在于它最大限度地减少了学习新技术的需要.最大的缺点是对程序逻辑的要求很大;很多事情需要你处理(文件会写成一个还是会发生任何一方捡到不一致的文件?应该多久执行一次检查?我需要担心文件系统吗,像缓存等?我可以稍后添加加密而不用玩弄我的程序代码之外的东西吗?...)
The advantage of this solution is that it minimizes the need for learning new techniques. The big disadvantage is that it has huge demands on the program logic; a lot of things need to be taken care of by you (Will the files be written in one piece or can it happen that any party picks up inconsistent files? How frequently should checks be implemented? Do I need to worry about the file system, like caching, etc? Can I add encryption later without toying around with things outside of my program code? ...)
如果可移植性是一个问题(据我从您的问题中了解到并非如此),那么该解决方案将很容易移植到不同的系统甚至不同的编程语言.但是,我不知道 iPhone 操作系统的任何网络文件系统,但我对此并不熟悉.
If portability was an issue (which, as far as I understood from your question is not the case) then this solution would be easy to port to different systems and even different programming languages. However, I don't know of any network files ystem for iPhone OS, but I am not familiar with this.
Sockets:编程接口肯定不同;根据您在套接字编程方面的经验,这可能意味着您有更多的工作先学习它,然后再调试它.实现:实际上,您将需要与以前类似的逻辑,即客户端和服务器通过网络进行通信.这种方法的一个明显优点是进程可以在推送"的基础上工作,即它们可以监听套接字直到消息到达,这优于定期检查控制文件.网络损坏和不一致也不是您关心的问题.此外,您(可能)对建立连接的方式有更多的控制权,而不是依赖于程序控制之外的事情(同样,如果您决定稍后添加加密,这很重要).
Sockets: The programming interface is certainly different; depending on your experience with socket programming it may mean that you have more work learning it first and debugging it later. Implementation: Practically, you will need a similar logic as before, i.e., client(s) and server(s) communicating via the network. A definite plus of this approach is that the processes can work on a "push" basis, i.e., they can listen on a socket until a message arrives which is superior to checking control files regularly. Network corruption and inconsistencies are also not your concern. Furthermore, you (may) have more control over the way the connections are established rather than relying on things outside of your program's control (again, this is important if you decide to add encryption later on).
优点是很多事情都从你的肩膀上卸下来了,这些事情会打扰 1 中的实现.缺点是你仍然需要大量改变你的程序逻辑,以确保你发送和接收正确的信息(文件类型等).
The advantage is that a lot of things are taken off your shoulders that would bother an implementation in 1. The disadvantage is that you still need to change your program logic substantially in order to make sure that you send and receive the correct information (file types etc.).
根据我的经验,可移植性(即易于转换到不同的系统甚至编程语言)非常好,因为任何与 POSIX 远程兼容的东西都可以工作.
In my experience portability (i.e., ease of transitioning to different systems and even programming languages) is very good since anything even remotely compatible to POSIX works.
[特别是,一旦您传达二进制数字节顺序就成为一个问题,您必须手动处理这个问题 - 这是的常见(!)特例正确的信息"我上面提到的问题.它会咬你,例如当您使用 PowerPC 与 Intel Mac 通话时.这种特殊情况在解决方案 3.+4 中消失了.将所有其他正确信息"问题放在一起.]
[ In particular, as soon as you communicate binary numbers endianess becomes an issue and you have to take care of this problem manually - this is a common (!) special case of the "correct information" issue I mentioned above. It will bite you e.g. when you have a PowerPC talking to an Intel Mac. This special case disappears with the solution 3.+4. together will all of the other "correct information" issues.]
+4.分布式对象 NSProxy
类簇用于实现分布式对象.NSConnection
负责设置远程连接,作为发送信息的先决条件,所以一旦你了解了如何使用这个系统,你也就了解了分布式对象.;^)
+4. Distributed objects: The NSProxy
class cluster is used to implement distributed objects. NSConnection
is responsible for setting up remote connections as a prerequisite for sending information around, so once you understand how to use this system, you also understand distributed objects. ;^)
这个想法是不需要更改您的高级程序逻辑(即,您的对象通过消息进行通信并接收结果,并且消息连同返回类型与您从本地实现中习惯的相同) 而不必担心网络基础设施的细节.好吧,至少在理论上.实施:我现在也在做这方面的工作,所以我的理解仍然有限.据我了解,您确实需要设置某种结构,即您仍然必须决定哪些进程(本地和/或远程)可以接收哪些消息;这就是 NSConnection
所做的.此时,你隐式定义了一个客户端/服务器架构,但是你不需要担心2中提到的问题.
The idea is that your high-level program logic does not need to be changed (i.e., your objects communicate via messages and receive results and the messages together with the return types are identical to what you are used to from your local implementation) without having to bother about the particulars of the network infrastructure. Well, at least in theory. Implementation: I am also working on this right now, so my understanding is still limited. As far as I understand, you do need to setup a certain structure, i.e., you still have to decide which processes (local and/or remote) can receive which messages; this is what NSConnection
does. At this point, you implicitly define a client/server architecture, but you do not need to worry about the problems mentioned in 2.
Gnustep 项目服务器上有介绍,有两个明确的例子;它说明了该技术的工作原理,并且是实验的一个很好的起点:http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_7.html
There is an introduction with two explicit examples at the Gnustep project server; it illustrates how the technology works and is a good starting point for experimenting:http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_7.html
不幸的是,缺点是完全失去了与其他系统的兼容性(尽管您仍然可以使用您提到的 Mac 和 iPhone/iPad 的设置)与其他系统以及无法移植到其他语言.使用 Objective-C 的 Gnustep 充其量是代码兼容的,但无法在 Gnustep 和 Cocoa 之间进行通信,请在此处查看我对问题 2 的Mac OS X (Cocoa) 上的 CORBA
Unfortunately, the disadvantages are a total loss of compatibility (although you will still do fine with the setup you mentioned of Macs and iPhone/iPad only) with other systems and loss of portability to other languages. Gnustep with Objective-C is at best code-compatible, but there is no way to communicate between Gnustep and Cocoa, see my edit to question number 2 here: CORBA on Mac OS X (Cocoa)
[我刚刚发现了另一条我不知道的信息.虽然我已经检查了 NSProxy
在 iPhone 上是否可用,但我没有检查分布式对象机制的其他部分是否可用.根据此链接:http://www.cocoabuilder.com/archive/cocoa/224358-big-picture-relationships-between-nsconnection-nsinputstream-nsoutputstream-etc.html(在页面中搜索短语iPhone OS")他们不是.如果您此时需要使用 iPhone/iPad,这将排除此解决方案.]
[ I just came across another piece of information that I was unaware of. While I have checked that NSProxy
is available on the iPhone, I did not check whether the other parts of the distributed objects mechanism are. According to this link: http://www.cocoabuilder.com/archive/cocoa/224358-big-picture-relationships-between-nsconnection-nsinputstream-nsoutputstream-etc.html (search the page for the phrase "iPhone OS") they are not. This would exclude this solution if you demand to use iPhone/iPad at this moment.]
总而言之,一方面学习(以及实施和调试)新技术的努力与另一方面手动编码较低级别的通信逻辑之间存在权衡.尽管分布式对象方法承担了您的大部分负担,并且对程序逻辑的更改最小,但它最难学习,而且(不幸的是)最不便于移植.
So to conclude, there is a trade-off between effort of learning (and implementing and debugging) new technologies on the one hand and hand-coding lower-level communication logic on the other. While the distributed object approach takes most load of your shoulders and incurs the smallest changes in program logic, it is the hardest to learn and also (unfortunately) the least portable.
这篇关于在 Mac OS X 上进行进程间通信的最佳方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!