我正在探索用 Erlang 编写应用程序的可能性,但它需要有一部分用 Cocoa(可能是 Objective-C)编写。我希望前端和后端能够轻松沟通。怎样才能最好地做到这一点?
我可以考虑使用 C 端口和连接的进程,但我想我想要一个相反的情况(前端启动并连接到后端)。有命名管道 (FIFO),或者我可以通过 TCP 端口或命名 BSD 套接字使用网络通信。有没有人有这方面的经验?
我正在探索用 Erlang 编写应用程序的可能性,但它需要有一部分用 Cocoa(可能是 Objective-C)编写。我希望前端和后端能够轻松沟通。怎样才能最好地做到这一点?
我可以考虑使用 C 端口和连接的进程,但我想我想要一个相反的情况(前端启动并连接到后端)。有命名管道 (FIFO),或者我可以通过 TCP 端口或命名 BSD 套接字使用网络通信。有没有人有这方面的经验?
一种方法是让应用程序的 Erlang 核心成为一个守护进程,Cocoa 前端使用您设计的一些简单协议通过 Unix 域套接字与之通信。
使用 Unix 域套接字意味着 Erlang 守护进程可以按需启动,launchd
而 Cocoa 前端可以通过环境变量找到要使用的套接字路径。这使得应用程序和守护程序之间的会合变得微不足道,并且还使得开发多个前端(或者可能是一个包装与守护程序通信的框架)变得简单。
Mac OS Xlaunchd
系统采用这种方式真的很酷。如果您指定作业应通过安全的 Unix 域套接字按需启动,launchd
则实际上将创建具有适当权限的套接字本身,并通过作业属性列表中命名的环境变量公布其位置。launchd
该作业在启动时实际上会在执行简单签入时将文件描述符传递给套接字。
最终这意味着前端打开套接字与守护进程通信、launchd
启动守护进程以及守护进程响应通信的整个过程是安全的,即使前端和守护进程运行在不同的特权级别.
一种方法是 Theo 使用 NSTask、NSPipe 和 NSFileHandle 的方法。您可以先查看 CouchDBX 的代码http://couchprojects.googlecode.com/svn/trunk/unofficial-binary-releases/CouchDBX/
端口是可能的,但一点都不好。
为什么这种通信不能简单地用 mochiweb 和 json 通信来处理,有什么原因吗?
通常在创建前面 UNIX 命令或其他无头程序的 Cocoa 应用程序时,您使用NSTask
:
使用 NSTask 类,您的程序可以将另一个程序作为子进程运行,并可以监视该程序的执行。一个 NSTask 对象创建一个单独的可执行实体;它与 NSThread 的不同之处在于它不与创建它的进程共享内存空间。
任务在由几个项目的当前值定义的环境中运行:当前目录、标准输入、标准输出、标准错误和任何环境变量的值。默认情况下,NSTask 对象从启动它的进程继承其环境。如果任务的任何值应该不同,例如,如果当前目录应该更改,则必须在启动任务之前更改值。任务运行时不能更改其环境。
您可以通过stdin
//stdout
与后端进程进行通信stderr
。BasciallyNSTask
是一个高级包装器exec
(或者fork
or system
,我总是忘记区别)。
据我了解,您不希望 Erland 程序成为连续运行的后台守护程序,但如果您这样做,请遵循@Chris 的建议。
NSTask 和 Unix 域套接字方法都是很好的建议。需要关注的是正在进行中的 Erlang FFI 实现:
erl_call 应该可以从 NSTask 中使用。我从 Textmate 命令中使用它,它非常快。将 erl_call 与 OTP gen_server 结合使用可以让您相对轻松地保持持久的后端状态。有关详细信息,请参阅我博客上关于 erl_call 的帖子。
使用 NSTask 你也可以考虑使用PseudoTTY.app(它允许交互式通信)!
另一个感兴趣的示例代码可能是 BigSQL,这是一个 PostgreSQL 客户端,它使用户能够将 SQL 发送到服务器并显示结果。
open -a Safari http://web.archive.org/web/20080324145441/http://www.bignerdranch.com/applications.shtml