Python Twisted Longpoll服务器:断开连接后请求循环仍然存在

Python Twisted Longpoll服务器:断开连接后请求循环仍然存在,python,twisted,Python,Twisted,我正试图用Twisted编写一个长轮询服务器,但恐怕我不了解请求管理 当客户端离开页面时,我可以看到它继续在控制台中循环。我认为当客户端断开连接时,实例会自行销毁 这就是我的目标,我想为每个连接的客户机分别运行DataService中的逻辑 以下是我所拥有的:(为了便于使用,我删减了这段代码,可能因此出现了一些语法错误,但它来自工作代码) 类数据服务(资源): 定义初始化(自我,sid): #设置循环调用 self.loopingCall=task.loopingCall(self.\u打印\u

我正试图用Twisted编写一个长轮询服务器,但恐怕我不了解请求管理

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

这就是我的目标,我想为每个连接的客户机分别运行DataService中的逻辑

以下是我所拥有的:(为了便于使用,我删减了这段代码,可能因此出现了一些语法错误,但它来自工作代码)

类数据服务(资源):
定义初始化(自我,sid):
#设置循环调用
self.loopingCall=task.loopingCall(self.\u打印\u数据)
self.loopingCall.start(5,False)
资源.\uuuu初始化(自)
self.sid=int(sid);
self.finished=False
#初始化响应
self.response=response={'status':1,'message':'OK','time':int(time.time()),'data':{}
def connectionLost(自身、原因):
self.loopingCall.stop();
def render_GET(自我,请求):
#响应将是json格式
request.setHeader('Content-Type','application/json')
#确保存在所需的GET变量
如果request.args中没有“lastupdate”:
self.loopingCall.stop()
返回ujson.dumps({'status':0,'message':'invalid query','data':{})
#从查询字符串设置上次更新时间戳
self.lastupdate=int(request.args['lastupdate'][0])
#设置self.request,以便我们可以在打印数据中访问它
self.request=请求
#呼叫打印数据
self.\u打印\u数据()
如果未自行完成:
返回服务器。尚未完成
定义打印数据(自):
#设置更新的数据
如果self.lastupdate0:
self.loopingCall.stop()
self.request.write(self.jsonpcallback++'('+ujson.dumps(response)+'))
self.request.finish()
self.finished=True
类数据服务器(资源):
def getChild(self、sid、request):
返回数据服务(sid)
当客户机离开页面时,我可以看到它继续在控制台中循环。我认为当客户机断开连接时,实例会自行销毁

事实并非如此。首先,实例只有在不再“可访问”时才会被销毁(就像您可能拥有的任何其他类型的对象一样)

执行此操作时:

self.loopingCall = task.LoopingCall(self.__print_data)
您正在创建一个对
self的引用。\uuu print\u data
,它有一个对
self
的引用。
LoopingCall
然后在反应器中注册自己(当您启动它时)。因此,现在反应器有一个对
self
的间接引用。因此
self
将永远存在,或者直到发生变化

您可以通过停止
LoopingCall
将其自身从反应器中注销。一旦反应器不再引用
LoopingCall
,它将不再保持
DataService
实例(
self
)的活动状态

如果要在客户端关闭连接时执行此操作,则需要使用
Request.notifyFinish
。虽然如此,但非常简单。您应该执行以下操作:

request.notifyFinish().addErrback(lambda ignored: self.loopingcall.stop())
这是一个错误,因为您只关心客户端关闭连接的情况,而不关心您关闭连接的情况

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

事实并非如此。首先,实例只有在不再“可访问”时才会被销毁(就像您可能拥有的任何其他类型的对象一样)

执行此操作时:

self.loopingCall = task.LoopingCall(self.__print_data)
您正在创建一个对
self的引用。\uuu print\u data
,它有一个对
self
的引用。
LoopingCall
然后在反应器中注册自己(当您启动它时)。因此,现在反应器有一个对
self
的间接引用。因此
self
将永远存在,或者直到发生变化

您可以通过停止
LoopingCall
将其自身从反应器中注销。一旦反应器不再引用
LoopingCall
,它将不再保持
DataService
实例(
self
)的活动状态

如果要在客户端关闭连接时执行此操作,则需要使用
Request.notifyFinish
。虽然如此,但非常简单。您应该执行以下操作:

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

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

感谢您解释得很好的答案!感谢您解释得很好的答案!