Twisted Longpoll Server:断开连接后请求循环仍然存在

时间:2011-12-07 20:19:27

标签: python twisted

我正在尝试使用Twisted编写一个longpolling服务器,但我担心我不理解请求管理。

当客户端离开页面时,我可以看到它继续在控制台中循环。我认为当客户端断开连接时,实例会自行销毁。

这就是我的目标,我想为每个连接的客户端单独运行DataService中的逻辑。

这就是我所拥有的:(为了方便消费,我把这个代码砍掉了,因为这可能是一些语法错误,但它来自工作代码)

class DataService(Resource):
    def __init__(self, sid):
        # set looping call
        self.loopingCall = task.LoopingCall(self.__print_data)
        self.loopingCall.start(5, False)
        Resource.__init__(self)
        self.sid = int(sid);
        self.finished = False

        # initialize response
        self.response = response = {'status':1, 'message': 'OK', 'time':int(time.time()), 'data': {}}

    def connectionLost(self, reason):
        self.loopingCall.stop();

    def render_GET(self, request):
        # response will be json format
        request.setHeader('Content-Type', 'application/json')
        # make sure required GET vars exist
        if 'lastupdate' not in request.args:
            self.loopingCall.stop()
            return ujson.dumps({'status':0,'message':'invalid query','data':{}})

        # set last update timestamp from query string
        self.lastupdate = int(request.args['lastupdate'][0])

        # set self.request so we can access it in __print_data
        self.request = request
        # call print data
        self.__print_data()

        if not self.finished:
            return server.NOT_DONE_YET

    def __print_data(self):

        # set updated data
        if self.lastupdate < self.myappobj.lastupdate
            self.response{'data']['items'] = {'foo':'bar'}

        # if updates were found, close loop, print, and finish request
        if len(response['data']) > 0:
            self.loopingCall.stop()
            self.request.write(self.jsonpcallback+'('+ujson.dumps(response)+')')
            self.request.finish()
            self.finished = True


class DataServer(Resource):
    def getChild(self, sid, request):
        return DataService(sid)

1 个答案:

答案 0 :(得分:1)

  

当客户端离开页面时,我可以看到它继续在控制台中循环。我认为当客户端断开连接时,实例会自行销毁。

没有。首先,实例只有在不再“可达”时才被销毁(就像你可能拥有的任何其他类型的对象一样)。

执行此操作时:

self.loopingCall = task.LoopingCall(self.__print_data)

您正在创建对self.__print_data的引用,其中引用了self。然后LoopingCall将自己注册到reactor(当你启动它时)。所以现在反应堆间接引用self。因此,self将永远存在,或直到某些变化。

您可以让LoopingCall通过停止来从反应堆取消注册。一旦反应堆不再引用LoopingCall,它将不再保持DataService实例(self)活着。

如果要在客户端关闭连接时执行此操作,则需要使用Request.notifyFinish。这是covered in the Twisted documentation,但它非常简单。你应该这样做:

request.notifyFinish().addErrback(lambda ignored: self.loopingcall.stop())

这是一个错误,因为您只关心客户端关闭连接的情况,而不是关闭连接的情况。