【问题标题】:Twisted Protocol Instance Variables?扭曲的协议实例变量?
【发布时间】:2013-06-02 07:20:14
【问题描述】:

客户:

#!/usr/bin/env python

from twisted.internet import reactor, protocol

class EchoClient(protocol.Protocol):
    def __init__(self, arg):
        self.arg = arg

    def connectionMade(self):
        self.transport.write("hello, world!")

    def dataReceived(self, data):
        print "Server said:", data
        self.transport.loseConnection()

    def connectionLost(self, reason):
        print "connection lost"

class EchoFactory(protocol.ClientFactory):
    protocol = EchoClient

    def buildProtocol(self, address):
        proto = protocol.ClientFactory.buildProtocol(self, address, 12)
        self.connectedProtocol = proto
        return proto

    def clientConnectionFailed(self, connector, reason):
        print "Connection failed - goodbye!"
        reactor.stop()

    def clientConnectionLost(self, connector, reason):
        print "Connection lost - goodbye!"
        reactor.stop()

def main():
    f = EchoFactory()
    reactor.connectTCP("localhost", 8000, f)
    reactor.run()

if __name__ == '__main__':
    main()

服务器:

#!/usr/bin/env python

from twisted.internet import reactor, protocol
from twisted.application import service, internet

class Echo(protocol.Protocol):
    def dataReceived(self, data):
        self.transport.write(data)

def main():
    factory = protocol.ServerFactory()
    factory.protocol = Echo
    reactor.listenTCP(8000,factory)
    reactor.run()

if __name__ == '__main__':
    main()

错误:

exceptions.TypeError: buildProtocol() takes exactly 2 arguments (3 given)

问题:

如何让CLIENT中的EchoClient类接受参数并分配实例变量(如上面EchoClient构造函数中的arg)?如下所述,之前有人建议我重写 buildProtocol 函数,但我这样做的尝试导致我出现上述错误。我不确定从这里去哪里。我想我的问题可以概括为:如何将实例变量添加到协议中?

【问题讨论】:

    标签: python oop networking twisted


    【解决方案1】:

    你写道:

    def buildProtocol(self, address):
        proto = protocol.ClientFactory.buildProtocol(self, address, 12)
    

    也就是说,您正在覆盖 ClientFactory.buildProtocol 并使用不同于它知道如何处理的签名调用父类。

    将数据从工厂传递到客户端只是有点棘手。您可以向工厂提供任何您想要的__init__,但twisted 会创建IProtocol 本身的实例。幸运的是,一旦准备就绪,大多数工厂都会将自己分配给协议的 factory 属性:

    class MyClientProtocol(protocol.Protocol):
        def connectionMade(self):
            # use self.factory here:
            self.transport.write(self.factory.arg)
    
    class MyClientFactory(protocol.ClientFactory):
        protocol = MyClientProtocol
    
        def __init__(self, arg):
            self.arg = arg
    

    其实整个ProtocolFactory业务都是支持这种使用的;但要注意; Protocol 的许多实例将共享其工厂的单个实例;使用工厂进行配置,但在协议中管理状态

    协议/工厂标准系列的实现方式当然有可能不适合您的需求,这也是合理的,只要您完全实现IProtocolIProtocolFactory 接口。基类的存在是因为它们为您处理大多数情况,而不是因为它们是唯一可能的实现。

    【讨论】:

      【解决方案2】:

      从你的问题中不清楚 究竟 你尝试了什么以及错误是什么究竟,但无论如何你必须做两个步骤:

      1. EchoClient 的构造函数接受你需要的任何参数,并初始化你需要它初始化的任何字段。
      2. 在您的工厂中重写 buildProtocol 方法以将这些参数提供给您的协议。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-17
        • 2012-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-10
        相关资源
        最近更新 更多