5

我在进程和子进程之间使用 Twisted 的 Perspective Broker 进行 RMI。

与其监听 TCP 套接字(例如通过传递reactor.listenTCP()的实例PBServerFactory)并让子进程连接到它,我更愿意使用子进程的标准输入和标准输出。

我找到了twisted.internet.stdio.StandardIO,但如果这是要走的路,我不确定如何设置所有内容。

在 stdio 上使用 PB 而不是 TCP 是否可行?如何?


等等,为什么?

子进程用于运行不受信任的代码。它是沙盒的,但需要能够以有限的方式与父进程通信。到目前为止,某种形式的 RMI 是针对特定用例的最简洁的选项,并且 PB 具有看起来正确的访问模型。但是沙盒进程没有——也不应该需要——网络访问。RMI 是它与外部世界的唯一通信,通过 stdin/stdout 进行管道传输似乎是一种干净的业务方式。

但是,如果我没有以正确的方式解决这个问题,那也是一个完全有效的答案。

4

1 回答 1

10

通过类似 stdio 的连接在父进程和子进程之间使用像 PB 这样的协议有两个部分。一件是在子进程中,使用文件描述符 0 和 1 与父进程通信。另一部分是父进程,使用与子进程的 0 和 1 对应的任何文件描述符。

StandardIO是第一块。你还需要第二块——那就是IReactorProcess.spawnProcess.

但是,较新的端点API 是访问此功能的更好方法。

端点的基础是客户端端点允许您连接到服务器而无需确切地关心该连接是如何建立的,而服务器端点允许您接受来自客户端的连接而不关心这些客户端是如何连接的。

有一个子进程客户端端点和一个 stdio 服务器端点。这意味着您可以编写您的客户端,例如:

factory = PBClientFactory(...)
d = factory.getRootObject()
...

clientEndpoint.connect(factory)

你的服务器是这样的:

factory = PBServerFactory(...)
...
serverEndpoint.listen(factory)

现在你有一个客户端和服务器可以相互通信,但你实际上还没有指定它们如何相互通信。也许是 TCP 或者是 stdio。

然后,您只需选择要使用的正确端点。要坚持您通过 stdio 进行通信的想法:

clientEndpoint = ProcessEndpoint(reactor, "/path/to/child", ("argv",), ...)
serverEndpoint = StandardIOEndpoint(reactor)

如果您稍后改变主意,那么切换到 - 比如说 - TCP 就像:

clientEndpoint = TCP4ClientEndpoint(reactor, "1.2.3.4", 12345)
serverEndpoint = TCP4ServerEndpoint(reactor, 12345)

或者,您可以使用用于端点字符串描述的插件机制将其转换为配置:

clientEndpoint = clientFromString(reactor, options["client-endpoint"])
serverEndpoint = serverFromString(reactor, options["server-endpoint"])

whereoptions["client-endpoint"]options["server-endpoint"]是字符串,如"tcp:host=1.2.3.4:port=12345""tcp:port=12345"

有关更多信息,请参阅完整的端点 howto

于 2013-05-20T11:58:16.447 回答