витая сеть getPage, 2 клиента в 2 классах, управление событиями между двумя - PullRequest
0 голосов
/ 29 июля 2010

Я пытаюсь создать программу-бридж в twisted.web, которая получает данные с веб-сервера и отправляет их на другой сервер, поэтому для удобства я использую 2 приложения getPage, которые для удобства обернуты в класс, класс содержит все обратные вызовы и клиентскую «рутину». 1) аутентификация 2) получение данных 3) отправка данных, все это выполняется циклически и отлично работает на обоих клиентах !!

То, что я планирую сделать сейчас, - это объединить их, это будет означать, что мне придется сделать несколько обратных вызовов вне классов для их обработки.

client1 <---> Основной <---> client2

Как я могу это сделать?

я использую витую getPage

я выложу один из двух классов

class ChatService():
    def __init__(self):
         self.myServID= self.generatemyServID()
         self.myServServer= "http://localhost"
         ## This is where the magic starts
             reactor.callWhenRunning(self.mainmyServ)
             reactor.run()

    def generatemyServID(self):
         a= ""
         for x in range(60):
            c= floor(random() * 61)
            a += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"[int(c):int(c)+1]
         return a

    def sentMessage(self, data):
        print "Message was sent successfully"

    def sendMessage(self, mess):
        s1= DeferredList([client.getPage(self.myServServer+"/chat/", headers={'Content-Type': 'application/x-www-form-urlencoded'}, method="POST", postdata="action=chat&user=%s&message=%s" % (self.myServID, mess)),])
        s1.addCallback(self.sentMessage)
        s1.addErrback(self.errMessage)

    def recivedMessage(self,data):
        chat= loads(data[0][1])
        if chat['from'] != "JOINED" and chat['from'] != "TYPING" and chat['from'] != "Ben":
            print "%s says: %s" % (chat['from'], decode(chat['chat']))
            self.sendMessage("Hello")
        # Restart Loop
        self.loopChat()

    def errMessage(self,e):
            # print "An error occured receiving/sending the messages\n%s" % e
        print "Still no connectiions, waiting..."
        self.loopChat()

    def loopChat(self):
        s1= DeferredList([client.getPage(self.myServServer+"/chat/", headers={'Content-Type': 'application/x-www-form-urlencoded'}, method="POST", postdata="action=poll&user=%s&message=null" % self.myServID),])
        s1.addCallback(self.recivedMessage)
        s1.addErrback(self.errMessage)   

    def error(self,e):
        print "An error occured\n%s" % e

    def connectedtomyServService(self,data):
        if data[0][0] == False:
            print "Connection to myServ Service was impossible"
            reactor.stop()
            return
        if loads(data[0][1])['action'] == 'join':
            print "Connected to the server and joined chat"
            print "Started chat loop"
            self.loopChat()
        else:
            print "An Error Occured"
            return

    def mainmyServ(self):
            # print "Client ID is: " + self.myServID
        # Joining Chat
        s1= DeferredList([client.getPage(self.myServServer+"/chat/", headers={'Content-Type': 'application/x-www-form-urlencoded'}, method="POST", postdata="action=join&user=%s&message=null" % self.myServID),])
        s1.addCallback(self.connectedtomyServService)
        s1.addErrback(self.error)

Как я могу делать обратные вызовы вне класса?

Надеюсь, мне удалось выразить себя = D

Большое спасибо

1 Ответ

2 голосов
/ 29 июля 2010

Как я могу сделать обратный вызов за пределами класса?

Это звучит как очень распространенное недоразумение. В результате недопонимания, вопрос, который задают, не имеет большого смысла. Итак, давайте забудем о вопросе.

У вас уже есть код, который использует Deferreds. Давайте начнем с mainmyServ:

def mainmyServ(self):
        # print "Client ID is: " + self.myServID
    # Joining Chat
    s1= DeferredList([client.getPage(self.myServServer+"/chat/", headers={'Content-Type': 'application/x-www-form-urlencoded'}, method="POST", postdata="action=join&user=%s&message=null" % self.myServID),])
    s1.addCallback(self.connectedtomyServService)
    s1.addErrback(self.error)

Во-первых, вы можете избавиться от DeferredList. В вашем списке только один Deferred, поэтому DeferredList не добавляет никакого значения. Вы получите практически такое же поведение, как это, и ваши обратные вызовы могут быть упрощены, удалив все выражения [0][0].

def mainmyServ(self):
        # print "Client ID is: " + self.myServID
    # Joining Chat
    s1= client.getPage(self.myServServer+"/chat/", headers={'Content-Type': 'application/x-www-form-urlencoded'}, method="POST", postdata="action=join&user=%s&message=null" % self.myServID)
    s1.addCallback(self.connectedtomyServService)
    s1.addErrback(self.error)

Так что это совершенно разумный метод, который вызывает функцию, которая возвращает Deferred, а затем добавляет обратный вызов и errback к этому Deferred. Скажем, у вас есть другая функция, возможно, ваша основная функция:

def main():
    service = ChatService()
    service.mainmyServ()

Что мешает функции main добавлять дополнительные обратные вызовы к Deferred в mainmyServ? Только это mainmyServ не удосуживается вернуть его. Итак:

def mainmyServ(self):
        # print "Client ID is: " + self.myServID
    # Joining Chat
    s1= client.getPage(self.myServServer+"/chat/", headers={'Content-Type': 'application/x-www-form-urlencoded'}, method="POST", postdata="action=join&user=%s&message=null" % self.myServID)
    s1.addCallback(self.connectedtomyServService)
    s1.addErrback(self.error)
    return s1


def main():
    service = ChatService()
    d = service.mainmyServ()
    d.addCallback(doSomethingElse)

Ничего особенного, это просто еще один addCallback. Все, что вам не хватало, - это ссылка на Deferred.

Теперь вы можете настроить цикл, doSomethingElse вызвав другой метод на ChatService. Если этот другой метод возвращает Deferred, тогда doSomethingElse может добавить к нему обратный вызов, который снова вызывает mainmyServ. И так далее. Вот твой цикл, контролируемый "снаружи" класса.

...