2012-02-17 2 views
1

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

Что я хочу достичь, так это то, что пользователь подключается к say example.com/get/1234, который является частью длинного опроса. 1234 - это идентификатор пользователя. Пока что он просто зависает и ждет контента. Затем пользователь использует новую вкладку/другой браузер/другой компьютер и т. Д. И идет по URL-адресу example.com/set/1234?data=abcd, где 1234 - это идентификатор пользователя, а данные - переменная с содержимым «abcd». Теперь, когда это произойдет, первый запрос на получение должен распечатать данные «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() 

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

ответ

1

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

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

1

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

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) 

EDIT: Лучше обходной путь будет использовать WebSockets + Redis + PubSub. Я не использовал это сам, но есть пример here.

+0

Спасибо вам за ответ @hymloth! Но это решение будет в основном зацикливаться и выполнять код сравнения постоянно - не будет ли это причиной проблем производительности, когда число пользователей растет? Если да, можно ли каким-то образом «приостановить» запрос во время ожидания ввода данных? – MonkeyPetteri

+0

Спасибо за обновление @hymloth - я это рассматривал, но кажется, что Firefox 3.x не поддерживает веб-сайты .. это требование. Любые другие идеи? – MonkeyPetteri

Смежные вопросы