认识tornado(四)
接下来我们看一下helloword.py的唯一一个handler。
1 class MainHandler(tornado.web.RequestHandler):
2 def get(self):
3 self.write("Hello, world")
它是tornado.web.RequestHandler的一个子类,覆盖了父类的get方法。get方法也极简单,直接写一个“hello world”字符串到客户端。
不难想到,Tornado在接到用户请求http://127.0.0.1:8888/时,最终会调用我们MainHandler的get方法。这中间经过了很多流程和逻辑,我们会一一跟踪并证实。
接下来再看main函数的下一句。
1 http_server = tornado.httpserver.HTTPServer(application)
看起来我们是新建了一个http server的实例,前面创建好的application作为参数传递构了httpserver的构造函数。HTTPServer类定义在 tornado/httpserver.py中。显然这是男主角。它的注释说明比Application还要长,需要重点关注。
tornadoe中的httpserver的概念,简单概括下来就是:读取客户端的http request,调用对应的handler,然后用HTTPServer.write函数把数据返回给客户端。
在注释中,作者举了一个最简单的例子来说明这个概念(甚至不需要用到Handler类的参与):
01 import tornado.httpserver
02 import tornado.ioloop
03
04 def handle_request(request):
05 message = "You requested %s\n" % request.uri
06 request.write("HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s" % (
07 len(message), message))
08 request.finish()
09
10 http_server = tornado.httpserver.HTTPServer(handle_request)
11 http_server.listen(8888)
12 tornado.ioloop.IOLoop.instance().start()
看到有多简单没有,一个handle_request函数就可以支撑起一个网站。当然,这个网站功能很简陋,不过是把客户的请求写回去而已。
你当然可以在handler_request函数里大作文章,针对不同的url执行不同的代码,同样能达到前面Handler机制的效果,不 过,tornado已经将这样的需求提炼出一套非常高效的handler机制,用起来也非常舒服。如果没有特别原因,就不必去“重复造轮子”的工作。
这也是为什么我们一般称之为web framework,tornado已经把一个http server各流程的基础框架搭好了,你只需要填填空,客制化,“装修”一下。
tornado 的HTTPServer会负责解析用户的HTTP Request,构造一个request对象。交给后面的RequestHandler处理。Request的解析是一个规范化的流程,基本不需要客制 化。针对Request的处理函数(即RequestHandler)才是重点被客户化的部分。
关于HTTPServer的分析将会占很大的篇幅,我们留在后面专门研究。在helloworld的分析中,我们只要记住,Application将会和HTTPServer实例绑定。
1 http_server.listen(options.port)
HTTP是工作在TCP协议上的,所以它其实是TCPServer的派生类。有过socket编程经验的读者都会记得,启动一个TCP服务器有三个必备步骤:
- create socket 创建socket。
- bind address 绑定地址。
- listen 执行侦听。
TCPServer类的实现顺理成章的借鉴了Unix/Linux中socket的机制。所以它也存在上面的几个步骤,并且这几个步骤都是在 HTTPServer.listen()函数调用时完成的。现在不会提这些细节,留在后面我们分析TCPServer这个类时再详查。
listen函数的参数是端口号,前面提到,tornado demo的默认端口号都是8888,从helloworld.py的前面几行就可以看到。
1 from tornado.options import define, options
2 define("port", default=8888, help="run on the given port", type=int)
define函数是OptionParser类的成员,定义在tornado/options.py中,机制与 parse_command_line()类似。上面就是定义了一个int变量,名为port,默认值为8888,还附带一个说明文字,厉害。port变 量会被存放进options对象的一个dictionary成员中。可以看到,访问方式就是options.port。执行完 http_server.listen(options.port),你的PC上就会在options.port这个端口上启动一个服务器,开始侦听用户 的连接。
看完前面的http_server.listen(),似乎感觉少点什么。对了,没有掉到关键的accept函数,用户连接又怎么处理呢?别急,马上就是。这一句看上去很玄乎的东西,其实就相当于我们熟悉的accept。
1 tornado.ioloop.IOLoop.instance().start()
那为什么不直接来个accept?这个IOLoop又是什么东西?
IOLoop与TCPServer之间的关系其实很简单。回忆用C语言写TCP服务器的情景,我们写好了create-bind-listen三段 式后,其实事情还不算完。我们还得写点代码处理accept/recv/send呢。通常我们会写一个无限循环,不断调用accept来响应客户端链接。 这个无限循环就是这里的IOLoop。这些代码让大家去写,最后其实都大同小异,因此tornado干脆写了一套标准代码,封装在IOLoop里。
IOLoop会负责accept这一步。你可以注释掉IOLoop这一行,然后再访问http://127.0.0.1:8888/,就会发现根本连不上服务器。通过抓包会发现,实际上服务器并没有响应连接请求。
对于recv/send操作,通常也是在一个循环中进行的,也可以抽象成IOLoop。我们分析HTTPServer类的实现时,会看到它是怎么借助IOLoop工作的。
到此为止我们的web server已经完备了。
我们在浏览器里输入http://127.0.0.1:8888/,浏览器就会连接到我们的服务器,把HTTP请求送到HTTPServer中。 HTTPServer会先parse request,然后将reqeust交给第一个匹配到的Handler。Handler负责组织数据,调用发送API把数据传到客户端。
认识tornado(一)
认识tornado(二)
认识tornado(三)
认识tornado(四)
认识tornado(五)
来源:http://www.nowamagic.net/academy/detail/1332566
认识tornado(四)的更多相关文章
- web框架详解之 tornado 四 模板引擎、session、验证码、xss
一.模板引擎 基本使用 继承,extends 页面整体布局用继承 导入,include 如果是小组件等重复的那么就用导入 下面是目录 首先在controllers里面创建一个文件,文件里面是页面类 # ...
- 16-1 djanjo介绍
一 web框架的本质 1用户的浏览器(socket客户端) 和 网站的服务器(socket服务端)之间 2 HTTP协议: 1.1 请求(request) 1.2. 响应(response) 3 we ...
- Python框架之Tornado(四)源码之褪去模板外衣
上一篇介绍了客户端请求在tornado框架中的生命周期,其本质就是利用epoll和socket来获取并处理请求.在上一篇的内容中,我们只是给客户端返回了简单的字符串,如:“Hello World”,而 ...
- 第二百六十四节,Tornado框架-基于正则的动态路由映射分页数据获取计算
Tornado框架-基于正则的动态路由映射分页数据获取计算 分页基本显示数据 第一步.设置正则路由映射配置,(r"/index/(?P<page>\d*)", inde ...
- Python之路(四十一):通过项目来深入理解tornado
Tornado之路 引子 与其感慨路难行,不如马上出发 目录 通过项目来深入理解tornado(一):tornado基础回顾 通过项目来深入理解tornado(二):AsyncHttpClient ...
- Python框架之Tornado(四)源码之褪去模板外衣的前戏
执行字符串表示的函数,并为该函数提供全局变量 本篇的内容从题目中就可以看出来,就是为之后剖析tornado模板做准备,也是由于该知识点使用的巧妙,所有就单独用一篇来介绍了.废话不多说,直接上代码: # ...
- 第四篇:白话tornado源码之褪去模板外衣的前戏
加班程序员最辛苦,来张图醒醒脑吧! ... ... ... 好了,醒醒吧,回归现实看代码了!! 执行字符串表示的函数,并为该函数提供全局变量 本篇的内容从题目中就可以看出来,就是为之后剖析tornad ...
- 潭州课堂25班:Ph201805201 tornado 项目 第四课 增加用户注册登录(课堂笔记)
tornado 相关说明 在 handlers 中创建个 auth.py 用来做用户登录,在这文件中创建个类,并逐步完善 在 tornado 中创建 login.html 文件,是个登录页面 {% e ...
- tornado用户指引(四)------tornado协程使用和原理(三)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/happyAnger6/article/details/51291221几种常用的协程方式: 1.回调 ...
随机推荐
- JSP简单练习-EL获取表单数据
输入username和password的界面: <%@ page language="java" contentType="text/html;charset=gb ...
- easyui datagrid动态设置行、列、单元格不允许编辑
Easyui datagrid 行编辑.列编辑.单元格编辑设置 功能: 动态对datagrid 进行行.列.单元格编辑进行设置不允许编辑. 禁用行编辑: 在编辑方法调用前,对选择的行进行判断,如果不允 ...
- 从构建分布式秒杀系统聊聊验证码 给大家推荐8个SpringBoot精选项目
前言 为了拦截大部分请求,秒杀案例前端引入了验证码.淘宝上很多人吐槽,等输入完秒杀活动结束了,对,结束了...... 当然了,验证码的真正作用是,有效拦截刷单操作,让羊毛党空手而归. 验证码 那么到底 ...
- UIPopoverController具体解释
今天一位童鞋问我个问题.大意是popoverController不会显示.经过我寻找问题发现以下这种方法不好掌控. 为什么说他不好掌控那.我这个给大家带来一个列子.通过这个列子来介绍PopoverCo ...
- Linux下自动备份Oracle数据库并删除指定天数前的备份
说明: Oracle数据库服务器 操作系统:CentOS IP:192.168.0.198 端口:1521 SID:orcl Oracle数据库版本:Oracle11gR2 具体操作: 1.root用 ...
- Java并发编程(二):JAVA内存模型与同步规则
一.Java内存模型(JMM) 它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式.一个线程如何和何时能看到其他线程共享变量的值,以及在 ...
- NGUI 取ScrollView中遮罩区域4个点
用panel.localCorners而不是panel.finalClipRegion,Region还要再换算 首先通过ScrollView取panel,然后取Corners,它返回值代表4个点,映射 ...
- 自己定义滑动删除item的ListView。
首先继承创建继承ListView和实现OnTouchListener,OnGestureListener的类. 会使用到AbsList中的pointToPosition(int x, int y)方法 ...
- 1.GCC编译过程
一. GCC编译过程 gcc -E hello.c -o hello.i // 预处理.将代码中包含的头文件和宏进行替换 gcc -S hello.i -o hello.s // 汇编.将当前文本转换 ...
- 微信中调起qq
http://wpa.qq.com/msgrd?uin={$qq}&menu=yes