Как завершить длинный опросный опрос Tornado при наличии данных - PullRequest
1 голос
/ 17 февраля 2012

У меня длинный опыт программирования, но я новичок в Python и играю с Tornado, чтобы создать прототип определенной длинной службы опросов.

Чего я хочу добиться, так это того, чтобы пользователь подключался, чтобы сказать example.com/get/1234, что является длинной частью опроса. 1234 - это идентификатор пользователя. На данный момент он просто висит и ждет контента. Затем пользователь использует новую вкладку / другой браузер / другой компьютер / и т. Д. И переходит по URL-адресу, например example.com/set/1234?data=abcd, где 1234 - это идентификатор пользователя, а данные - это переменная с содержимым «abcd». Теперь, когда это происходит, первый запрос get должен распечатать данные «abcd» и завершить запрос. Идентификатор пользователя используется, очевидно, чтобы позволить нескольким пользователям использовать сервис одновременно. Проще говоря:

1) Перейти на example.com/get/1234 -> ожидание 2) В другой вкладке откройте example.com/set/1234?data=abcd 3) Сразу после этого запроса первый запрос печатает abcd и завершает

Ниже я попробую кое-что сделать, но я не продвигаюсь вперед и не могу найти подходящие ключевые слова Google для решения этой проблемы.

class GetHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous

    # Getting user ID is working
    def get(self, user_id):

        # This is something I'm not sure is right, but found it in an 
        # example. I haven't created the code_received function yet, 
        # nor know if it should be here? Should the code_received
        # and connection finishing be called from the /set part?

        cursor = self.get_argument("cursor", None)
        self.wait_for_code(self.code_received, cursor=cursor)

    def code_received(self, data)
        self.write(data)
        self.finish()

Вся помощь очень ценится. Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 28 февраля 2012

Мне действительно удалось это исправить, я нашел решение .

Просто подведу итог, если кто-то еще рассматривает это: я сохранил слушателей под диктовку с user_id и когда был вызван /set, я отправил слушателю сообщение с тем же user_id. Если кому-то интересно, могу поделиться большим кодом.

1 голос
/ 17 февраля 2012

Простой обходной путь заключается в добавлении обратного вызова тайм-аута

class GetHandler(tornado.web.RequestHandler):

    @tornado.web.asynchronous
    def get(self, user_id):    

        def check():
            # here you must implement something to discover if the result exists
            # for example, you can keep a dictionary with id : result 
            # so initially 1234 : None
            # after setting 1234 : someVal (this happens from the SetHandler)
            # then if below succeeds
            if there_is_a_result:
                self.write(result) 
                self.finish()
            else:   # result not ready, add another timeout callback
                tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(0.00001), check)

        tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(0.00001), check)

РЕДАКТИРОВАТЬ: Лучшим обходным решением будет использование websockets + redis + pubsub.Я не использовал это сам, но есть пример здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...