0

我正在实现一个具有以下基本结构的 API:

  1. 运行服务器A
  2. 客户端连接到serverA并发送数据
  3. ServerA 处理数据并将其发送到 serverB
  4. 服务器 B 回复服务器 A
  5. ServerA 根据从 serverB 接收到的输入响应客户端的请求

到目前为止,我尝试了两种解决方案:

1)使用httplib创建一个标准的非扭曲TCP连接来处理从serverA到serverB的请求。然而,这在 httplib 调用期间有效地阻塞了服务器。

2)创建第二个继承自protocol.Protocol的类并使用

factory = protocol.ClientFactory()
factory.protocol = Authenticate
reactor.connectSSL("localhost",31337,factory, ssl.ClientContextFactory())

在 serverA 和 serverB 之间创建连接。但是,这样做时,我似乎无法从请求类的回调中访问原始的客户端到服务器的连接。

在 Twisted 中处理这种设置的正确方法是什么?

4

1 回答 1

2

“client-to-serverA”连接由与传输关联的协议实例表示。这些都是常规的旧 Python 对象,因此您可以将它们作为参数传递给函数或类初始化程序,或者将它们设置为其他对象的属性。

例如,如果你有ClientToServerAProtocol一个fetchServerBData方法被调用以响应从客户端接收到的一些字节,你可以这样写:

class ClientToServerAProtocol(Protocol):
    ...
    def fetchServerBData(self, anArg):
        factory = protocol.ClientFactory()
        factory.protocol = Authenticate
        factory.clientToServerAProtocol = self
        reactor.connectSSL("localhost",31337, factory, ssl.ClientContextFactory())

由于ClientFactory将自身设置为factory它创建的任何协议的属性,Authenticate因此由此产生的实例将能够说“self.factory.clientToServerAProtocol”并获得对该“客户端到服务器A”连接的引用。

这种方法有很多变化。这是另一个,使用最近引入的端点 API:

from twisted.internet.endpoints import SSL4ClientEndpoint

class ClientToServerAProtocol(Protocol):
    ...
    def fetchServerBData(self, anArg):
        e = SSL4ClientEndpoint(reactor, "localhost", 31337, ssl.ClientContextFactory()) 
        factory = protocol.Factory()
        factory.protocol = Authenticate
        connectDeferred = e.connect(factory)
        def connected(authProto):
            authProto.doSomethingWith(self)
        connectDeferred.addCallback(connected)

这里的基本思想相同 - 用于self引用您对Authenticate协议感兴趣的“client-to-serverA”连接。在这里,我使用了一个嵌套函数来 ''close over'' self。这只是您在程序的正确部分获得参考的众多选项中的另一个。

于 2012-11-30T13:10:05.387 回答