Twisted:在connectTCP后关闭连接而不影响其他连接

3 投票
1 回答
6220 浏览
提问于 2025-04-17 18:28

我刚接触Twisted,想弄明白怎么实现以下功能。
我有一个服务器,它接收来自客户端的消息。不过,这个服务器在收到消息后,会把消息转发给另一个服务器。
所以大致上是这样的:

Client --->   Server1  --->   Server2

简单来说,Server1既是一个服务器,也是一个客户端。不过,在Server1把信息发送给Server2之后,我想让Server1和Server2断开连接。我不太确定该怎么做。

现在我已经实现的功能是,客户端把信息发送给Server1。我对输入做了一些修改,然后调用了reactor.connectTCP(),这成功地连接并发送信息给Server2。我的问题是,如何在不完全关闭Server1的情况下,关闭与Server2的连接。我尝试使用transport.loseConnection(),但这会在与Server2断开连接时关闭Server1。

我在考虑用reactor.spawnProcess()来实现,但我无法让它工作。从我看到的情况来看,当我关闭连接时,它会关闭整个进程,所以如果我能用另一个进程进行connectTCP,就不应该影响其他进程。

这是我的代码:

import time, datetime
import re
from twisted.internet import stdio, reactor, protocol
from twisted.protocols import basic

result = 'The AT message is unavailable (no previous talk with client)'

class DataForwardingProtocol(protocol.Protocol):
    def __init__(self):
        self.output = None
        self.normalizeNewlines = False

    def dataReceived(self, data):
        if self.normalizeNewlines:
            data = re.sub(r"(\r\n|\n)", "\r\n", data)
        if self.output:
            self.output.write(data)

class StdioProxyProtocol(DataForwardingProtocol):
    global result
    def connectionMade(self):
        inputForwarder = DataForwardingProtocol()
        inputForwarder.output = self.transport
        inputForwarder.normalizeNewlines = True
        stdioWrapper = stdio.StandardIO(inputForwarder)
        self.output = stdioWrapper
        self.transport.write(result)
        self.transport.loseConnection( )

class StdioProxyFactory(protocol.ClientFactory):
    protocol = StdioProxyProtocol

    def clientConnectionLost(self, transport, reason):
        reactor.stop()

    def clientConnectionFailed(self, transport, reason):
        print reason.getErrorMessage()
        reactor.stop()

class EchoProtocol(basic.LineReceiver):

    def dataReceived(self, line):
      #Do stuff with the input sent from the client.  This is irrelevant to my problem.
                #UPDATE OTHER SERVERS
                reactor.connectTCP('localhost', 12771, StdioProxyFactory())   

class EchoServerFactory(protocol.ServerFactory):
    protocol = EchoProtocol

if __name__ == "__main__":
    port = 12770
    reactor.listenTCP(port, EchoServerFactory( ))
    reactor.run( )

谢谢!

1 个回答

8

你的Server1正在关闭,因为你在工厂的clientConnectionLost()方法里调用了reactor.stop(),而不是因为调用了transport.loseConnection()。你可能不想在第一个出站连接丢失后就立刻关闭整个反应器。

撰写回答