在Twisted中正确访问协议的传输方式是什么?
在这个TCP客户端的例子中:
from twisted.internet import reactor, protocol
# a client protocol
class EchoClient(protocol.Protocol):
"""Once connected, send a message, then print the result."""
def connectionMade(self):
self.transport.write("hello, world!")
def dataReceived(self, data):
"As soon as any data is received, write it back."
print "Server said:", data
self.transport.loseConnection()
def connectionLost(self, reason):
print "connection lost"
class EchoFactory(protocol.ClientFactory):
protocol = EchoClient
def clientConnectionFailed(self, connector, reason):
print "Connection failed - goodbye!"
reactor.stop()
def clientConnectionLost(self, connector, reason):
print "Connection lost - goodbye!"
reactor.stop()
# this connects the protocol to a server runing on port 8000
def main():
f = EchoFactory()
reactor.connectTCP("localhost", 8000, f)
reactor.run()
# this only runs if the module was *not* imported
if __name__ == '__main__':
main()
我有一个定期需要向服务器发送数据的任务。这个任务的所有逻辑都在协议和工厂之外。把f
传来传去,然后用f.protocol.transport.write("Something?")
来发送数据,这样做算不算不太好呢?
2 个回答
0
我也是刚接触Twisted这个框架,所以我的看法仅供参考,但我觉得这是可以接受的做法。
你可以看看我在下面这个StackOverflow上的回答,里面有个例子讲了怎么把Twisted的各个部分连接起来:Twisted中的持久连接。(顺便提一下,那篇回答也提到了定时任务……)
编辑
哦,等等。你里面有一个工厂。
这个工厂每次有连接时都会创建一个新的协议实例,所以你的f.protocol.transport.write
是行不通的(因为protocol
指向的是类,而不是一个已经连接的实例)。你可以试试我在持久连接问题中的代码示例,我在工厂里创建了一个连接列表(就是self.clients
),通过这个结构你可以遍历连接列表,使用不同连接的.write
方法。
2
你可以重新组织你的代码,利用一些比较新的接口,这样就不用在工厂里做额外的工作来实现你的目标。Mike Lutz的回答是完全正确的,这也是我以前建议大家在没有端点的时候使用的方法。现在有了端点,我建议大家使用这些端点。
端点接口让你可以写一个看起来更像这样的主函数:
def main():
e = HostnameEndpoint(reactor, "localhost", 8000)
f = EchoFactory()
d = e.connect(f)
d.addCallback(connected)
return d
def connected(protocol):
# protocol is an instance of EchoClient and is connected
return LoopingCall(doStuff, protocol).start(3)
你也可以考虑把这个改成使用 twisted.internet.task.react
,这样可以帮你处理一些反应器的管理工作。