簡體   English   中英

扭曲為客戶端/服務器的問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM