Twisted Longpoll Server: цикл запроса сохраняется после отключения - PullRequest
1 голос
/ 08 декабря 2011

Я пытаюсь написать сервер с длинным опросом для Twisted, но боюсь, что не понимаю управление запросами.

Когда клиент уходит со страницы, я вижу, что он продолжает цикл в консоли. Я думал, что экземпляр просто разрушится, когда клиент отключится.

И это моя цель, я хочу запускать логику в 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 Ответ

1 голос
/ 15 декабря 2011

Когда клиент уходит со страницы, я вижу, что он продолжает цикл в консоли.Я думал, что экземпляр просто разрушится, когда клиент отключится.

Это не так.Во-первых, экземпляры уничтожаются только тогда, когда они больше не «достижимы» (как и любой другой объект, который у вас может быть).

Когда вы делаете это:создание ссылки на self.__print_data, которая имеет ссылку на self.LoopingCall затем регистрируется в реакторе (когда вы его запускаете).Так что теперь реактор имеет косвенную ссылку на self.Так что self будет жить вечно или до тех пор, пока что-то не изменится.

Вы можете заставить LoopingCall отменить свою регистрацию в реакторе, остановив его.Как только реактор больше не ссылается на LoopingCall, он больше не будет поддерживать экземпляр DataService (self) живым.

Если вы хотите сделать это, когда клиент закрывает соединение, тогдаВы хотите использовать Request.notifyFinish.Это описано в документации Twisted , но это довольно просто.Вы должны сделать что-то вроде этого:

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

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

...