[英]Twisted as a client/server problems
我正在使用Twisted创建“客户端/服务器”,该程序充当客户端以获取一些数据,并用作服务器以重新发送此数据或仅将其他数据发送给客户端。
我正在使用twisted,我的代码初始化工厂如下所示:
application = service.Application('monitorD', uid=0, gid=0)
factoryMonitord = ServerFactory(p)
internet.TCPServer(9000, factoryMonitord).setServiceParent(service.IServiceCollection(application))
#because I need to send some datas from client factory to clients of serverfactory
factoryScamd = ClientFactory(factoryMonitord)
internet.TCPClient("localhost", 8001, factoryScamd).setServiceParent(service.IServiceCollection(application))
我的问题是客户端部分无法连接(因为服务器不可用)时,它似乎“阻塞”了我所有的服务器部分。 我的服务器部分和其他客户端之间仍然可以进行通信,但速度确实很慢...(而且当我的客户端部分可以连接时,它就可以正常工作)。
在此先感谢您的帮助。
编辑:
这是我的ServerFactory代码(很多无用的代码...):
class ServerFactory(protocol.ServerFactory):
protocol = ServerProtocol
def __init__(self, portal):
#self.tp = ClientFactory.tp
self.tp = []
self.portal = portal
self.loop_vol_raid_areca = LoopingCall(self.checkVolRaidAreca)
self.loop_vol_raid_areca.start(30)
self.loop_services = LoopingCall(self.checkServices)
self.loop_services.start(30)
def buildProtocol(self, addr):
p = protocol.ServerFactory.buildProtocol(self, addr)
p.portal = self.portal
return p
def sendList(self, data):
if data:
if isinstance(data, list):
for element in data:
if isinstance(element, list):
self.clean_data = "".join(element)
self.sendToClients(self.clean_data)
def sendToClients(self, data):
print "SEND to MonitorC from MonitorD, tp:", self.tp
if data:
for tp in self.tp:
self.protocol.sendLine(tp, data)
def checkServices(self):
self.scamd = threads.deferToThread(checkScamd)
self.scamd.addCallback(self.sendToClients)
self.httpd = threads.deferToThread(checkHttpd)
self.httpd.addCallback(self.sendToClients)
self.postgres = threads.deferToThread(checkPostgres)
self.postgres.addCallback(self.sendToClients)
def checkVolRaidAreca(self):
self.vol = threads.deferToThread(check_vol_areca)
self.vol.addCallback(self.sendList)
self.event = threads.deferToThread(get_last_event_areca)
self.event.addCallback(self.sendList)
这是客户端工厂,其中包含许多无用的代码:
class ClientFactory(protocol.ClientFactory):
protocol = ClientProtocol
def __init__(self, MonitordFactory):
self.tp = MonitordFactory.tp
def clientConnectionFailed(self, connector, reason):
print "Connection to scamd failed - retrying..."
time.sleep(30)
connector.connect()
def clientConnectionLost(self, connector, reason):
print "Connection to scamd lost - retrying..."
time.sleep(30)
connector.connect()
def getCamList(self, data):
cams_list = data.split("\x00")
self.cams_array = []
for i in cams_list:
if str.find(i, "camera") != -1:
i = i.split(" ")
i = filter(lambda x: len(x)>0, i)
self.cams_array.append(i)
def checkCams(self, data):
data = data.split(" ")
for i in self.cams_array:
if i[1] == data[2]:
if data[3] == "-1":
msg = i[6] + " ERREUR -1"
if data[3] == "0":
msg = i[6] + " ERREUR 0"
if data[3] == "1":
msg = i[6] + " ERREUR 1"
if data[3] == "2":
msg = i[6] + " ERREUR 2 (RECO)"
return msg
如果需要更多信息,我会将整个代码发布到pastebin。 而且,我是python AND twisted的新手(但是我以前用C或C ++编写代码)
您应该可以立即改变两件事。 摆脱time.sleep(30)
调用。 另外,您正在大量使用线程池,因此可能需要增加线程池的大小。 您每30秒创建5个线程,并且由于反应堆线程池大小默认为5,因此您创建的任何其他线程最终都将在这5个线程之后等待。我在想一堆排队的线程可能在等待您的创建服务运行速度更慢甚至出现阻塞。
短期内,您可以在ServerFactory中创建自己的twisted.python.threadpool.Threadpool
:
class ServerFactory(protocol.ServerFactory):
protocol = ServerProtocol
def __init__(self, portal):
# ...
self.threadpool = ThreadPool(25, 50)
def checkServices(self):
# ...
self.postgres = threads.deferToThreadPool(reactor, self.threadpool, checkPostgres)
但是,从长远来看,您应该考虑使用异步API处理服务。
例如,可以使用twisted.web.client.Agent使您的checkHttpd
代码异步。 对于PostgreSQL,您可以使用txPostgres 。 我不熟悉上面的scamd
服务,因此使用异步IO连接到它可能会更加困难(即:您可能必须为该服务编写协议的异步版本)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.