tornado使用总结

2019/03/30 技术

tornado使用总结

1. 请求参数解析

  • 获取请求消息体: self.request.body
  • 获取请求参数(query, form-data, …): self.get_argument("name", None) # 必须指定默认值, 不然找不到key时会触发异常
  • 获取请求参数列表(query, form-data, …): self.get_arguments("name[]") # 找不到key, 返回空列表; 不能设置默认值
  • 获取请求参数object: self.get_argument("people[name]"), self.get_arguments("people[friend][]")

2. 异步/并发

使用线程池+yield实现异步:

from concurrent.futures import ThreadPoolExecutor
import tornado
from tornado.concurrent import run_on_executor
from tornado.web import RequestHandler
import time


class SimpleAsyncServer(RequestHandler):
    def __init__(self, application, request, **kwargs):
        super(SimpleAsyncServer, self).__init__(application, request, **kwargs)
        self.executor = ThreadPoolExecutor(10)

    @tornado.gen.coroutine
    def get(self, ):
        print("on get...")
        result = yield self._do_something()

        self.write(result)

    @run_on_executor
    def _do_something(self, ):
        """
            模拟耗时操作
        :return:
        """
        time.sleep(5)
        return {"msg": "OK"}

3. 先响应再执行后续操作

处理一个请求时, 可以显式调用self.finish(), 向客户端返回响应, 接着在服务端继续处理剩下的记录日志等业务.

如:

def post(self, ):
    # 写入响应内容
    self.write({"code": 200, "msg": "OK"})
    
    # 返回响应: 客户端能拿到结果
    self.finish()
    
    # 处理剩下的业务
    self.logger.info("logging request...")
    time.sleep(60)
    self.logger.info("done!")

4. 返回响应

返回json

返回json结果, 最简单的方法是直接把dict传给self.write(dict_obj), self.write会在内部将响应内容转为str, 并设置header.

实际使用的过程中, 遇到过客户端解析结果, 因为单/双引号问题, 导致json解析错误. 为降低风险, 直接这样调用:

self.set_header("Content-Type", "application/json; charset=UTF-8")
self.write(json.dumps(result))

返回二进制数据

有时候为了方便测试, 会在响应中直接返回二进制内容.

如服务端直接返回pickle序列化后的数据:

self.write(pickle.dumps(data))

客户端可以这样解析:

import pickle
import requests
response = requests.post(xxx)
data = pickle.loads(response.content) # object

5. 压缩数据

app = tornado.web.Application([
    (r'/file', FileUploadHandler),
],
compress_response=True,
)
app.listen(8080)
tornado.ioloop.IOLoop.instance().start()

Search

    Table of Contents