我正在构建一个具有本地使用类的程序,但我希望通过网络以相同的方式使用相同的类。这意味着我需要能够对其任何公共方法进行同步调用。该类读写文件,因此我认为XML-RPC开销过高。我使用twisted中的示例创建了一个基本的rpc客户端/服务器,但是我遇到了客户端问题。
c = ClientCreator(reactor, Greeter)
c.connectTCP(self.host, self.port).addCallback(request)
reactor.run()
这适用于单个调用,当收到数据时我正在调用reactor.stop(),但是如果我再进行一次调用,反应器将不会重启。还有什么我应该用的吗?可能是一个不同的扭曲模块或另一个框架?
(我没有详细说明协议是如何工作的,因为重点是我只能接到一个电话。)
附录&澄清:
我与谷歌文档分享了我正在做的事情。 http://docs.google.com/Doc?id=ddv9rsfd_37ftshgpgz
我有一个使用保险丝的版本,可以将多个本地文件夹组合到保险丝安装点。文件访问已经在一个类中处理,所以我想让服务器给我网络访问同一个类。在继续搜索之后,我怀疑pyro(http://pyro.sourceforge.net/)可能是我真正想要的(仅仅基于现在阅读他们的主页)但我对任何建议持开放态度。
我可以通过使用nfs mount并将其与我的本地文件夹组合来实现类似的结果,但我希望所有对等体都可以访问相同的组合文件系统,因此这将要求每台计算机都具有nfs服务器nfs挂载的数量等于网络中的计算机数量。
结论: 我决定使用rpyc,因为它给了我正是我想要的东西。一个服务器,它保存一个我可以操作的类的实例,就好像它是本地的一样。如果有人有兴趣我将我的项目放在Launchpad(http://launchpad.net/dstorage)上。
答案 0 :(得分:2)
如果您甚至考虑使用Pyro,请先查看RPyC,然后重新考虑XML-RPC。
关于Twisted:尝试离开反应堆而不是停止反应堆,每次只需ClientCreator(...).connectTCP(...)
。
如果您在协议中self.transport.loseConnection()
,则不会保持打开连接。
答案 1 :(得分:2)
为什么你觉得它需要同步?
如果要确保一次只发生其中一个,请通过DeferredSemaphore调用所有调用,以便对实际调用(对任意值)进行速率限制。
如果您希望能够在不同时间运行多个这些流,但不关心并发限制,那么您应该至少将反应器启动和拆除与调用分开(反应堆应该在整个生命周期内运行)该过程)。
如果你无法弄清楚如何在反应堆模式中表达应用程序的逻辑,你可以使用deferToThread并编写一大块纯粹的同步代码 - 尽管我猜这不是必需的。
答案 2 :(得分:1)
对于同步客户端,Twisted可能不是正确的选项。相反,您可能希望直接使用套接字模块。
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.host, self.port))
s.send(output)
data = s.recv(size)
s.close()
recv()
调用可能需要重复,直到你得到一个空字符串,但这显示了基础知识。
或者,您可以重新安排整个程序以支持异步调用...
答案 3 :(得分:1)
如果你使用Twisted,你应该知道:
reactor.stop()
),直到您的应用程序准备好退出。我希望这能回答你的问题。我个人认为Twisted 完全是您用例的正确解决方案,但您需要解决同步性问题。
附录&澄清:
我不明白的部分原因是 当我调用reactor.run()时 似乎只是进入一个循环 观看网络活动。我如何能 继续跑我剩下的 程序虽然它使用网络?如果 我可以过去,然后我可以 可能通过 同步问题。
这正是reactor.run()的作用。它运行一个主循环,它是一个事件反应器。它不仅会等待诱人的事件,还会等待你计划发生的任何事情。使用Twisted,您需要以处理其异步性质的方式构建应用程序的其余部分。也许如果我们知道它是什么样的应用程序,我们可以提供建议。