我正在尝试使用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)
答案 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())
这是一个错误,因为您只关心客户端关闭连接的情况,而不是关闭连接的情况。