簡體   English   中英

Python Twisted 向代理發送事件信號的最佳方式

[英]Python Twisted best way to signal events to a proxy

我將托管一項服務,該服務的行為有點像我作為客戶的某物的代理。

所以我希望我的 ProxyService(一個twisted.protocol 服務器)需要很多參與者(客戶端)。 在服務器端,我需要一個到 ExistingService 的全局連接(所有客戶端只需要 1 個連接)(代碼不是我寫的,我是它的客戶端)。

  • 當 ExistingService 說了一些有趣的事情時,我需要將它廣播給所有演員。
  • 當演員對我的 ProxyService 說些什么時,我需要檢查它對我來說是否合適。 如果是這樣,我需要通知 ExistingService。

我想我知道如何使用全局變量來解決這個問題,但只是想知道是否有更好的方法來推送消息。

在此處輸入圖片說明

您已經建立了良好的基本設計。 這是一種基本的“中間人”方法。 有很多方法可以實現它,但這應該會讓你開始:

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()

允許將從服務器接收到的數據代理到actors 的核心邏輯是proxy_factory.actors = set()actor_factory.actors = proxy_factory.actors 大多數“類似列表”的容器,由於缺乏更好的詞,都是“全局的”,這個例子為每個連接的工廠對象提供了上下文。 當參與者連接到服務器時, Actor協議被附加到set ,當接收到數據時, set每個協議都會獲取數據。 請參閱每個協議對象的相應dataReceived()方法,了解其工作原理。

上面的例子根本沒有使用全局變量,但這並不是說你不能使用它們。 看看使用這種傳遞將上下文提供給其他對象的變量的方法可以走多遠。 此外,某些情況未明確處理,例如在服務器或參與者尚未連接的情況下緩存接收到的數據。 希望這里有足夠的信息供您根據需要確定最佳行動方案。 還有一些空間可以簡化語法以使其更短。

作為旁注。 全局變量的替代方案是picobox 這是一個依賴注入器庫,但我發現當我需要來自外部來源的參數時,它可以滿足我的大部分需求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM