【问题标题】:What is the correct way to access a protocols transport in Twisted?在 Twisted 中访问协议传输的正确方法是什么?
【发布时间】:2014-04-27 22:31:20
【问题描述】:

在 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?") 是不是很糟糕?

【问题讨论】:

    标签: python twisted


    【解决方案1】:

    您可以重构您的代码并利用一些新的 API,以避免在工厂中进行额外的工作来实现您的目标。 Mike Lutz 的回答是完全正确的,也是我过去在端点之前向人们提出的建议。现在我们有了端点,我建议人们改用它们。

    端点 API 让您可以编写一个看起来更像这样的主函数:

    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,它将为您处理一些反应堆簿记。

    【讨论】:

      【解决方案2】:

      我对 Twisted 世界也很陌生,所以对我持保留态度,但我说它可以接受的形式。

      请参阅以下内容,如果我举了一个如何将扭曲部分连接在一起的示例:Persistent connections in twisted。 (碰巧这个答案也谈到了周期性任务......)

      编辑

      哎呀,等等。你在那里有一家工厂。

      每次有连接时,工厂都会创建协议的新实例,因此您的 f.protocol.transport.write 将不起作用(protocol 将指向该类,而不是该类的已连接实例)。尝试从Persistent connections 问题运行我的代码示例,我制作了一个连接列表(工厂中的self.clients),使用该结构您可以通过遍历连接列表来使用各种连接的.write

      【讨论】:

        猜你喜欢
        • 2019-12-20
        • 1970-01-01
        • 1970-01-01
        • 2016-03-19
        • 2017-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多