【问题标题】:Twisted server-client data sharing扭曲的服务器-客户端数据共享
【发布时间】:2012-06-04 04:17:33
【问题描述】:

我在这个站点上稍微修改了一个服务器-客户端 Twisted 程序,它提供了一个可以充当服务器和客户端的程序 (How to write a twisted server that is also a client?)。我能够将服务器客户端连接到一侧的外部客户端和另一侧的外部服务器。我想通过服务器-客户端程序将数据从外部客户端传输到外部服务器。我遇到的问题是将 ServerProtocol 类(在服务器-客户端程序中)中接收到的行放入 ClientProtocol 类(在服务器-客户端程序中)。我尝试了多种方法,包括尝试使用工厂引用,正如您从 def init 中看到的那样,但我无法让它工作。 (目前我只是将文字来回发送到外部服务器和客户端)这是服务器-客户端代码:

    from twisted.internet import protocol, reactor
    from twisted.protocols import basic


    class ServerProtocol(basic.LineReceiver):        
        def lineReceived(self, line):
            print "line recveived on server-client",line
            self.sendLine("Back at you from server-client")
            factory = protocol.ClientFactory()
            factory.protocol = ClientProtocol
            reactor.connectTCP('localhost', 1234, factory)

    class ClientProtocol(basic.LineReceiver):
        def __init__(self, factory):
            self.factory = factory

        def connectionMade(self):
            self.sendLine("Hello from server-client!")
            #self.transport.loseConnection()
        
        def lineReceived(self, line):
            print "line recveived on server-client1.py",line
            #self.transport.loseConnection()
          
    def main():
        import sys
        from twisted.python import log

        log.startLogging(sys.stdout)
        factory = protocol.ServerFactory()
        factory.protocol = ServerProtocol
        reactor.listenTCP(4321, factory)
        reactor.run()

    if __name__ == '__main__':
        main()

我应该提到,我能够分别在端口 4321 和 1234 上使用外部服务器和外部客户端连接到服务器-客户端程序,它们只是回显。此外,我还没有展示我多次尝试使用 self.factory 参考。任何意见或建议将不胜感激。

【问题讨论】:

    标签: twisted


    【解决方案1】:

    这个问题与 Twisted FAQ 中的一个热门问题非常相似:

    How do I make input on one connection result in output on another?

    FAQ 项目谈论到一台服务器的许多客户端连接,而不是关于一个传入客户端连接和一个传出客户端连接的问题,这没有任何显着差异。您在不同连接之间共享数据的方式是相同的。

    该常见问题解答项目的基本要点是,基本上您想做的任何事情都涉及某种方法调用,并且 Twisted 中的方法调用与任何其他 Python 程序中的方法调用相同。您所需要的只是引用正确的对象来调用该方法。因此,例如,调整您的代码:

    from twisted.internet import protocol, reactor
    from twisted.protocols import basic
    
    class ServerProtocol(basic.LineReceiver):        
        def lineReceived(self, line):
            self._received = line
            factory = protocol.ClientFactory()
            factory.protocol = ClientProtocol
            factory.originator = self
            reactor.connectTCP('localhost', 1234, factory)
    
        def forwardLine(self, recipient):
            recipient.sendLine(self._received)
    
    class ClientProtocol(basic.LineReceiver):
        def connectionMade(self):
            self.factory.originator.forwardLine(self)
            self.transport.loseConnection()
    
    def main():
        import sys
        from twisted.python import log
    
        log.startLogging(sys.stdout)
        factory = protocol.ServerFactory()
        factory.protocol = ServerProtocol
        reactor.listenTCP(4321, factory)
        reactor.run()
    
    if __name__ == '__main__':
        main()
    

    注意方法:

    • 我摆脱了ClientProtocol 上的__init__ 方法。 ClientFactory 调用其协议时不带任何参数。需要参数的__init__ 将导致引发TypeError。此外,ClientFactory 已经将自己设置为它创建的协议的工厂属性。
    • 我通过将ServerProtocol 实例设置为客户端工厂的originator 属性,为ClientProtocol 提供了对ServerProtocol 实例的引用。由于ClientProtocol 实例引用了ClientFactory 实例,这意味着它引用了ServerProtocol 实例。
    • 我添加了forwardLine 方法,一旦ClientProtocol 连接建立,ClientProtocol 可以使用该方法来指导ServerProtocol 执行您的应用程序逻辑是什么。请注意,由于上一点,ClientProtocol 调用此方法没有问题。

    【讨论】:

    • 感谢您的参考。我正在尝试使其适应我的程序(您实际上是在不久前发布的)。但是,我应该提到传出连接实际上是到服务器。也许这不应该有任何区别,但我想我应该指出这一点。非常感谢。
    • 在我之前的回复中,我尝试将数据发送到另一台服务器而不是客户端似乎确实有所不同。我尝试在上面的 ServerProtocol 中创建一个 factory.serverconnections[],然后在 ClientProtocol 中使用它,这样我就可以将数据从外部客户端连接传递到外部服务器连接,但是我得到了无法识别列表的错误在后者。我会继续尝试,但如果您能在我的方式中看到明显的错误,请指出。
    • 非常感谢您让我明白并花时间解释如何使用 Twisted 中的方法。这是一个非常好的和优雅的解决方案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 2011-03-15
    • 2023-03-23
    • 1970-01-01
    • 2012-09-27
    相关资源
    最近更新 更多