将可可前端写入Erlang应用程序的好方法是什么?
我正在探索用Erlang编写应用程序的可能性,但是它需要用Cocoa(大概是Objective-C)编写一部分。我希望前端和后端能够轻松通信。如何最好地做到这一点?
我可以考虑使用C端口和连接的进程,但是我想我想做相反的事情(前端启动并连接到后端)。有命名管道(FIFO),或者我可以通过TCP端口或者命名的BSD套接字使用网络通信。有人在这方面有经验吗?
解决方案
回答
一种方法是让应用程序的Erlang核心成为守护进程,可可前端使用我们设计的一些简单协议通过Unix域套接字与之进行通信。
Unix域套接字的使用意味着Erlang守护程序可以由launchd
按需启动,而Cocoa前端可以通过环境变量找到要使用的套接字的路径。这使得应用程序和守护程序之间的会合变得微不足道,并且还使得开发多个前端(或者可能是包装与守护程序通信的框架)变得很简单。
Mac OS X的" launchd"系统真的很酷。如果我们指定应通过安全的Unix域套接字按需启动作业,则launchd
实际上会创建具有适当权限的套接字本身,并通过作业属性列表中命名的环境变量来公布其位置。作业启动时,实际上会在执行简单检入时通过launchd
将文件描述符传递给套接字。
最终,这意味着,即使前端和守护程序在前端运行,整个前端打开套接字以与守护程序进行通信,"启动"启动守护程序以及响应该通信的守护程序的整个过程也是安全的。不同的特权级别。
回答
通常,当创建可支持UNIX命令或者其他无头程序的Cocoa应用程序时,可以使用" NSTask":
Using the NSTask class, your program can run another program as a subprocess and can monitor that program’s execution. An NSTask object creates a separate executable entity; it differs from NSThread in that it does not share memory space with the process that creates it. A task operates within an environment defined by the current values for several items: the current directory, standard input, standard output, standard error, and the values of any environment variables. By default, an NSTask object inherits its environment from the process that launches it. If there are any values that should be different for the task, for example, if the current directory should change, you must change the value before you launch the task. A task’s environment cannot be changed while it is running.
我们可以通过stdin
/stdout
/stderr
与后端进程进行通信。基本上,NSTask是围绕exec(或者fork或者system的高级包装,我总是会忘记两者之间的区别)。
据我了解,我们不希望Erland程序成为连续运行的后台守护程序,但是如果我们愿意,请遵循@Chris的建议。
回答
一种方法是Theo使用NSTask,NSPipe和NSFileHandle的方法。我们可以先查看CouchDBX的代码http://couchprojects.googlecode.com/svn/trunk/unofficial-binary-releases/CouchDBX/
端口是可能的,但一点都不好。
为什么有些通讯无法简单地通过mochiweb和json通讯进行处理?
回答
NSTask和Unix域套接字方法都是不错的建议。需要注意的是正在开发的Erlang FFI实现:
http://muvara.org/crs4/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