python - 扭曲为客户端/服务器问题

标签 python client twisted block

我正在使用 twisted 来创建一个“客户端/服务器”,该程序作为客户端获取一些数据,并作为服务器重新发送此数据或仅向客户端发送其他数据。

我正在使用 twistd,我的工厂初始化代码如下所示:

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 的新手并且很扭曲(但我曾经用 C 或 C++ 编写代码)

最佳答案

您应该能够立即更改两件事。去掉 time.sleep(30) 调用。此外,您正在大量使用线程池,因此您可能希望增加它的大小。每 30 秒您创建 5 个线程,并且因为 react 器线程池大小默认为 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 来处理您的服务。

例如,您的checkHttpd 代码可以通过使用twisted.web.client.Agent 变成异步的。 .对于 PostgreSQL,您可以使用 txPostgres .我不熟悉上面的 scamd 服务,因此使用异步 IO 连接到它可能更加困难(即:您可能必须为该服务编写协议(protocol)的异步版本)。

关于python - 扭曲为客户端/服务器问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5900000/

相关文章:

php - 实时获取 Ratchet php中断开连接的客户端的客户端资源ID

javascript - 使用javascript(客户端)将来自两个不同视频的两个片段组合成一个视频?

python - 使用 Python 和 Twisted 的 DNS 服务器 - 异步操作的问题

python - 如何识别扭曲的客户端?

python - mutate()为参数 'name'获取了多个值

python - pandas 数据框中按时间间隔分组

javascript - AngularJS 和企业应用程序

database - Django ORM 数据库查询会阻塞服务器,还是异步的?

python - 使用 Altair 增加条形图中的条宽

python - 如何检查数组中至少五个元素的邻域是否满足标准?