Python Twisted动态协议,用于在运行时发送数据包

时间:2014-02-25 00:34:46

标签: python twisted distributed-system

我最近开始使用Python Twisted,虽然它非常复杂但我真的很喜欢它!我已经尝试寻找答案,但我一直在干涸,所以我希望有人在这里是一个扭曲的大师:

我有一个大型/复杂的分布式系统设置,采用分层格式,包括主设备,从设备,子设备等。 在我的代码中的几个点,取决于收到的数据包,我需要将数据包发送到另一个节点。在调用reactor.run()之前,不知道数据需要发送到的节点,所以我觉得答案可能不同。我希望连接是TCP的可靠性,但它只需要发送一个数据包。有时我需要回复,有时我不需要,但之后连接总是会死。我一直在处理这个问题的当前方法是保持对我的类中reactor的引用,该引用是发送数据包并调用的:

tmpConn = MyClientFactory(dataToSend)
self.reactor.connectTCP(ADDR, PORT, tmpConn)

我觉得这可能会带来一些问题:

  • 如果我不保留对tmpConn
  • 的引用,垃圾收集会发生什么
  • 如果我在课堂上保留对它的引用,那么它最终会变成垃圾,因为它只需要发送一个数据包。

正如我所说,有许多不同的工厂同时做这样的事情,所以我想知道这是否是处理这种情况的最佳方法。任何指针都非常感谢。

这是一个代码段,因此问题更加明确。

from twisted.internet import reactor
from twisted.internet.protocol import Protocol, Factory, ClientFactory

class OneShotProtocol(Protocol):
    def __init__(self, addr, data):
        self.myaddr = addr
        self.mydata = data

    def connectionMade(self):
        # We know we have a connection here so send the data
        self.transport.write(self.mydata)
        # Now we can kill the connection
        self.transport.loseConnection()

class OneShotFactory(ClientFactory):
    def __init__(self, data):
        self.mydata = data

    def buildProtocol(self, addr):
        return OneShotProtocol(addr, self.mydata)

class ListenProtocol(Protocol):
    def __init__(self, addr, factory):
        self.myaddr = addr
        #NOTE: I only save this because I've read multiple reactors are possible
        self.factory = factory

    def dataReceived(self, data):
        if(data == 'stuff'):
            #Alert the other node!
            tmpConn = OneShotFactory('The British are coming')
            self.factory.reactor.connectTCP(ADDR, PORT, tmpConn)
        # Moving on...

class ListenFactory(Factory):
    def __init__(self, reactor):
        self.reactor = reactor

    def buildProtocol(self, addr):
        return OneShotProtocol(addr, self)

l = ListenFactory(reactor)
reactor.listenTCP(PORT, l)
reactor.run()

1 个答案:

答案 0 :(得分:0)

这听起来像是实现所需行为的好方法。

您不必非常担心工厂的垃圾收集。反应堆将保留对它的引用(毕竟你将它传递给connectTCP,只要它需要然后忘记它。如果你也忘了它,那么Python的垃圾收集器会在很长时间之前为你清理它。

您可能想要做的唯一调整是使用酷炫的新"endpoint" APIs而不是使用connectTCP目录。这并没有改变解决方案的基本思想,它只是给你一点灵活性,你可能有一天会受益。