我使用以下代码解决了这个问题。 RPC 是添加新代理的管理服务器,ProxyClient 会覆盖 twisted.protocols.portforward.ProxyClient
基本上,我必须自己跟踪客户并在我想终止他们的传输时调用 abortConnection。
from twisted.internet import protocol, reactor, error
from twisted.web import xmlrpc, server
from twisted.python import log, failure
import socket
class RPC(xmlrpc.XMLRPC):
proxies = {} # (host, port): tcp.Port()
clients = [] # list of active client transports
def __get(self, host, port):
if (host, port) in self.proxies.keys():
return self.proxies.get((host, port))
return self.__new(host, port)
def __new(self, host, port):
factory = ProxyFactory(host, port)
tcp_port = reactor.listenTCP(0, factory)
self.proxies[(host, port)] = tcp_port
return tcp_port
def xmlrpc_get(self, host, port):
log.msg('get {}'.format(host, port))
port = self.__get(host, port)
return port.getHost().port
def xmlrpc_kill(self, host, port):
log.msg('kill {}'.format(host, port))
tcp_port = self.proxies.pop((host, port), None)
if not tcp_port:
return False
tcp_port.loseConnection() # don't listen anymore
try:
ip = socket.gethostbyname(host)
except:
return False
for client in list(self.clients):
# kill connections now because we're anxious
peer = client.getPeer()
if (ip, port) == (peer.host, peer.port):
log.msg('abort {}'.format(client))
client.abortConnection()
self.clients.remove(client)
return True
class ProxyClient(Proxy):
def connectionMade(self):
RPC.clients.append(self.transport)
self.peer.setPeer(self)
# Wire this and the peer transport together to enable
# flow control (this stops connections from filling
# this proxy memory when one side produces data at a
# higher rate than the other can consume).
self.transport.registerProducer(self.peer.transport, True)
self.peer.transport.registerProducer(self.transport, True)
# We're connected, everybody can read to their hearts content.
self.peer.transport.resumeProducing()
def connectionLost(self, reason):
if self.transport in RPC.clients:
RPC.clients.remove(self.transport)