Tornado包含一个AsyncHTTPClient类,可以执行异步HTTP请求。
关键字: @tornado.web.asynchronous
,self.finish()
import tornado.web
import tornado.httpclient
class IndexHandler(tornado.web.RequestHandler):
# @tornado.web.asynchronous装饰器告诉Tornado保持连接开启。
@tornado.web.asynchronous
def get(self):
query = self.get_argument('q')
client = tornado.httpclient.AsyncHTTPClient()
#fetch方法并不返回调用的结果,而是使用callback指定的函数处理response。
client.fetch(url,callback=self.on_response)
def on_response(self, response):
...
pass
self.finish()
#显式地告诉Tornado关闭连接
1.调用@tornado.web.asynchronous装饰器
2.必须调用 self.finish() 已完成 HTTP 请求,否则 用户的浏览器会一直处于等待服务器响应的状态
记住当你使用@tornado.web.asynchonous装饰器时,asynchronous 装饰器是让请求变成长连接的方式,必须手动调用 self.finish() 才会响应,asynchronous 装饰器不会自动调用self.finish() ,如果没有没有指定结束,该长连接会一直保持直到 pending 状态。 (否则,请求将可能挂起,浏览器可能不会显示我们已经发送给客户端的数据。)
上面的方法有些麻烦,为了处理请求 ,把代码分割成两个不同的方法,当有两个或更多的异步请求要执行的时候,编码和维护都显得非常困难。
一个更整洁的方式来执行异步请求————协程异步函数
关键字:@tornado.gen.coroutine
,yield
特点:
- 需要使用 coroutine 装饰器
- 返回值需要使用 raise gen.Return() 当做异常抛出。(Python3.2以后可用return直接返回)
import tornado.gen
class IndexHandler(tornado.web.RequestHandler):
@tornado.gen.coroutine
def get(self):
query = self.get_argument('q')
client = tornado.httpclient.AsyncHTTPClient()
response = yield tornado.gen.Task(client.fetch,url)
body = json.loads(response.body)
raise gen.Return(body)
#self.finish()
yield
的使用返回程序对Tornado的控制,允许在HTTP请求进行中执行其他任务。当HTTP请求完成时,RequestHandler方法在其停止的地方恢复,然后继续运行。
gen.coroutine 在 Tornado 3.1 后会自动调用 self.finish()
结束请求,不必显示调用self.finish()
关闭连接。
使用过 Python 生成器应该知道,想要启动生成器的话必须手动执行 next() 方法才行,所以这里的 coroutine 装饰器的其中一个作用就是在调用这个异步函数时候自动执行生成器。
Reference:真正的 Tornado 异步非阻塞
使一切异步————异步访问数据库
一个重要的例子是bit.ly的asyncmongo,它可以异步的调用MongoDB服务器。这个库是我们的一个非常不错的选择,因为它是专门给Tornado开发者开发提供异步数据库访问的,不过对于使用其他数据库的用户而言,在这里也可以找到不错的异步数据存储库的选择。
提示:如果你正在设计一个希望客户端浏览器来执行搜索请求,而让Web服务器转向提供其他请求。在大多数情况下,你至少希望将结果缓存以便两次相同搜索项的请求不会导致再次向远程API执行完整请求。
Tornado与WebSockets
WebSockets是HTML5规范中新提出的客户-服务器通讯协议。提供了在客户端和服务器间持久连接的双向通信。协议本身使用新的ws://URL格式,但它是在标准HTTP上实现的。通过使用HTTP和HTTPS端口,它避免了从Web代理后的网络连接站点时引入的各种问题。
参看:http://demo.pythoner.com/itt2zh/ch5.html#ch5-3
网友评论