twisted web 获取页面,两个类中的两个客户端,管理二者之间的事件

0 投票
1 回答
917 浏览
提问于 2025-04-16 02:00

我正在尝试创建一个桥接程序,使用 twisted.web 来接收来自一个网络服务器的数据,并将其发送到另一个服务器。为此,我使用了两个 getPage 应用程序,并把它们封装在一个类里,这样更方便。这个类包含了所有的回调函数和客户端的“流程”…… 1)认证 2)接收数据 3)发送数据,所有这些都是循环进行的,在两个客户端中都运行得很好!

我现在计划将这两个客户端整合在一起,这意味着我需要在类外部做一些回调,以便处理它们。

客户端1<--->主程序<--->客户端2

我该怎么做呢?

我正在使用 twisted 的 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

我该如何在类外部使用回调函数?

这个问题听起来像是一个很常见的误解。由于这个误解,提问的方式其实并不太合理。所以我们不如先不纠结这个问题。

你已经有一些使用了Deferred的代码。我们先从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的函数,然后为这个Deferred添加一个回调和一个错误回调。假设你还有另一个函数,也许是你的主函数:

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

是什么阻止main函数为mainmyServ中的Deferred添加更多的回调呢?只是因为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。如此循环下去。这样就形成了一个在类“外部”控制的循环。

撰写回答