如何在Twisted中从服务器进行解除阻塞连接?

时间:2012-11-30 08:40:46

标签: client twisted nonblocking

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

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

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

    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中处理这样设置的正确方法是什么?

1 个答案:

答案 0 :(得分: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并获取对“client-to-serverA”连接的引用。

这种方法有很多变化。这是另一个,使用最近推出的端点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”连接。在这里,我使用嵌套函数“'关闭''self。这只是您参与程序正确部分的众多选项中的另一个。