龙卷风长轮询请求

时间:2013-06-16 17:10:31

标签: python tornado long-polling

以下是我的问题最简单的例子:

当发出请求时,它将打印Request via GET <__main__.MainHandler object at 0x104041e10>,然后请求将保持打开状态。好!但是,当您发出另一个请求时,它不会调用MainHandler.get方法,直到第一个连接完成。

如何让多个请求进入get方法,同时让它们保持长轮询。我正在通过每个请求传递参数,这些参数将通过redis从pub / sub获得不同的结果。问题是我一次只能获得一个连接。怎么了?为什么这会阻止其他请求?

import tornado.ioloop
import tornado.web
import os


class MainHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        print 'Request via GET', self


if __name__ == '__main__':
    application = tornado.web.Application([
        (r"/", MainHandler)])

    try:
        application.listen(int(os.environ.get('PORT', 5000)))
        tornado.ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        tornado.ioloop.IOLoop.instance().stop()

左图:如上所述。请求不按右图所示的方式处理。 右图我需要请求(a-d)由RequestHandler处理,然后等待pub / sub宣布他们的数据。

       a  b   c   d
       +  +   +   +                        ++          a    b   c   d
       |  |   |   |                        ||          +    +   +   +
       |  |   |   |                        ||          |    |   |   |
       |  |   |   |                        ||          |    |   |   |
       |  |   |   |                        ||          |    |   |   |
       |  v   v   v                        ||          |    |   |   |
   +---|-----------------------------+     ||    +-----|----|---|---|------------------+
   |   |                             |     ||    |     |    |   |   |                  |
   |   +               RequestHandler|     ||    |     +    +   +   +     RequestHan.  |
   |   |                             |     ||    |     |    |   |   |                  |
   +---|-----------------------------+     ||    +-----|----|---|---|------------------+
   +---|-----------------------------+     ||    +-----|----|---|---|------------------+
   |   |                             |     ||    |     |    |   |   |                  |
   |   +                Sub/Pub Que  |     ||    |     v    +   v   v         Que      |
   |   |                             |     ||    |          |                          |
   +---|-----------------------------+     ||    +----------|--------------------------+
   +---|-----------------------------+     ||    +----------|--------------------------+
       |                                   ||               |
       |                 Finished          ||               |               Finished
       v                                   ||               v
                                           ||
                                           ||
                                           ||
                                           ||
                                           ||
                                           ||
                                           ||
                                           ++

如果可以使用其他编程语言完成,请告诉我。

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

来自http://www.tornadoweb.org/en/stable/web.html#tornado.web.asynchronous

  

tornado.web.asynchronous(方法)

     

...

     

如果给出了这个装饰器,那么当响应没有完成时   方法返回。由请求处理程序调用self.finish()   完成HTTP请求。没有这个装饰器,请求是   当get()或post()方法返回时自动完成。

您必须明确地完成get方法:

import tornado.ioloop
import tornado.web
import tornado.options

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)

class MainHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        print 'Request via GET', self
        self.finish()


if __name__ == '__main__':
    application = tornado.web.Application([
        (r"/", MainHandler)])

    try:
        application.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        tornado.ioloop.IOLoop.instance().stop()