【问题标题】:Python Twisted best way to signal events to a proxyPython Twisted 向代理发送事件信号的最佳方式
【发布时间】:2017-12-29 05:48:05
【问题描述】:

我将托管一项服务,该服务的行为有点像我作为客户的代理。

所以我希望我的 ProxyService(一个 twisted.protocol 服务器)接收很多参与者(客户端)。在服务器端,我需要一个全局连接(所有客户端只需要一个连接)到 ExistingService(我没有编写的代码,我是它的客户端) .

  • 当 ExistingService 说一些有趣的事情时,我需要将它广播给所有参与者。
  • 当演员对我的 ProxyService 说些什么时,我需要检查它是否适合我。如果是,我需要通知 ExistingService。

我想我知道如何使用全局变量来解决这个问题,但只是想知道是否有更好的方法来推送消息。

【问题讨论】:

  • 您是否在问如何在没有全局变量的情况下执行此操作?询问“更好的方法”是非常开放的。

标签: python asynchronous events proxy twisted


【解决方案1】:

您已经建立了良好的基本设计。 这是一种基本的“中间人”方法。 有很多方法可以实现它,但这应该可以帮助您入门:

from twisted.internet import endpoints, protocol, reactor


class ProxyClient(protocol.Protocol):

    def connectionMade(self):
        print('[x] proxy connection made to server')
        self.factory.proxy_proto = self

    def connectionLost(self, reason):
        print('[ ] proxy connection to server lost: {0}'.format(reason))
        self.factory.proxy_proto = None

    def dataReceived(self, data):
        print('==> received {0} from server'.format(data))
        print('<== transmitting data to all actors')
        for actor in self.factory.actors:
            actor.transport.write(data)


class Actor(protocol.Protocol):

    def connectionMade(self):
        print('[x] actor connection established')
        self.factory.actors.add(self)

    def connectionLost(self, reason):
        print('[ ] actor disconnected: {0}'.format(reason))
        self.factory.actors.remove(self)

    def dataReceived(self, data):
        print('==> received {0} from actor'.format(data))
        proxy_connection = self.factory.proxy_factory.proxy_proto
        if proxy_connection is not None:
            print('<== transmitting data to server through the proxy')
            proxy_connection.transport.write(data)
        else:
            print('[ ] proxy connection to server has not been established')


def setup_servers():
    PROXY_HOST = '127.0.0.1'
    PROXY_PORT = 9000
    proxy_factory = protocol.ClientFactory()
    proxy_factory.protocol = ProxyClient
    proxy_factory.proxy_proto = None
    proxy_factory.actors = set()
    proxy_client = endpoints.TCP4ClientEndpoint(reactor, port=PROXY_PORT, host=PROXY_HOST)
    proxy_client.connect(proxy_factory)

    ACTOR_HOST = '127.0.0.1'
    ACTOR_PORT = 8000
    actor_factory = protocol.Factory()
    actor_factory.protocol = Actor
    actor_factory.proxy_factory = proxy_factory
    actor_factory.actors = proxy_factory.actors
    actor_server = endpoints.TCP4ServerEndpoint(reactor, port=ACTOR_PORT, interface=ACTOR_HOST)
    actor_server.listen(actor_factory)


def main():
    setup_servers()
    reactor.run()


main()

允许从服务器接收到的数据被代理给actor的核心逻辑是proxy_factory.actors = set()actor_factory.actors = proxy_factory.actors。 大多数“类似列表”的容器,因为没有更好的词,是“全局的”,这个例子为每个连接的工厂对象提供了上下文。 当参与者连接到服务器时,Actor 协议会附加到set 中,当接收到数据时,set 中的每个协议都会获取数据。 请参阅每个协议对象各自的 dataReceived() 方法,了解其工作原理。

上面的例子根本没有使用全局变量,但这并不是说你不能使用它们。 看看使用这种将变量传递给其他对象的方法能走多远。 此外,某些情况没有明确处理,例如在服务器或参与者尚未连接的情况下缓存接收到的数据。 希望这里有足够的信息供您根据需要确定最佳行动方案。 还有一些空间可以简化语法以使其更短。

作为旁注。全局变量的替代方法是picobox。这是一个依赖注入器库,但我发现当我需要来自外部源的参数时,它可以满足我的大部分需求。

【讨论】:

    猜你喜欢
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    相关资源
    最近更新 更多