当初之所以突然捡起python以及体验tornado,源自忘了哪里看到的一篇文章,说tornado十一个简洁高效的web server以及框架,总共代码两千多行,所以懒人义无反顾的抱起来研究。
上次说的那个Options还好,不小心打开了web.py,尼嘛,光这个一个文件就超过两千行(2.4.1),坑爹啊。。。谁乱说的来着?
考虑到这个文件尼嘛太大了,所以分开研究,依旧是看点儿写点儿。。。所以这一篇只记录Application这个类。
基本上所有的tornado的入门的文章都逃不出这个例子,当然,这篇也不能例外:
application = web.Application([ (r"/", MainPageHandler), ]) http_server = httpserver.HTTPServer(application) http_server.listen(8080) ioloop.IOLoop.instance().start()
很明显,在这个例子中tornado依赖于Application类构造函数中的参数来构建路由映射规则,那这个参数有几个特点:
- 列表
- 每一个列表项都是一个元组
- 每一个元组至少包含了两个参数(为什么说至少,是因为其实还可以包含第三个参数)
- 元组的第一项是一个正则表达式,用来定义路由的filter
- 元组的第二项是一个类,tornado会用这个类的实例来处理相应的路由映射
所以,按照上面的分析,很容易根据需要定义出自己的路由规则表,借用tornado中blog的例子:
(r"/", HomeHandler), (r"/archive", ArchiveHandler), (r"/feed", FeedHandler), (r"/entry/([^/]+)", EntryHandler), (r"/compose", ComposeHandler), (r"/auth/login", AuthLoginHandler), (r"/auth/logout", AuthLogoutHandler),
根据传说中的common sense,所有路由规则中包含wildcard字符的路由规则项,他们在tornado处理的时候,会赋给较低的优先级,毕竟我们不想(.*)$这样的路由规则抢了其他所有人的饭碗,就像这个。。。。。
当然,对于好学的我必须很好奇,除了这个参数之外,还有其他的可选项嘛?所以来看看Application类的构造函数,不过具体的代码和分析就不写了,太长。。。要打好多字。。。
Application构造函数接受的其他参数:
- default_host。当tornado接受到request但是没有指定handler或者没有能够匹配的handler的时候,使用default_host做自动跳转。(不过看了一下Application的构造函数,总觉得不科学啊。。唯一能够触发这种场景的例子貌似就是一个handler都不加,否则想像不出来神码东西可以逃出.*$这样的黑洞。。。)
- transforms。也不知道干啥的
- wsgi。更不知道干啥的。。。
- settings。这个我知道,可以包含对于Application这个web server的配置项,这个太长,放到下一个小标题讲。
默认Application会处理的Settings项:
- gzip。一旦指定gzip,会自动添加一个GZipContentEncoding,用来处理被GZip压缩过的数据。
- ui_modules。不知到是干啥的。。。不过tornado会自己自动添加三个UI Modules:linkify, xsrf_form_html, Template。
- ui_methods。尼嘛还是不知到是干嘛地。。。。
- debug。用来保证tornado运行在debug模式
-
static_path。服务器端存放静态文件(图像,CSS,etc.)的相对目录。如果指定了static_path,tornado就会接着在settings中寻找其他几个配置项,包含:
static_url_prefix: 从当前位置指向包含静态文件的目录的“相对路径”
static_handler_class: 类,其实例用来处理客户端对于静态文件的请求
static_handler_args: 字典,包含用来初始化static_handler_class实例,所需要的参数
需要注意的是,不管你愿不愿意,tornado都会帮你自动添加如下四个路由映射规则:
- $static_path/(.*) ---> static_handler_class
- /favicon.icon ---> static_handler_class
- /robots.txt ---> static_handler_class
- .*$ --->所有传入Application构造函数的handler
--------------------------------------------------------------------------------------------------------------2013-1-24
补充一下,在handler中提到,还可以定义以下的settings项:
if "template_loader" in settings: return settings["template_loader"] kwargs = {} if "autoescape" in settings: # autoescape=None means "no escaping", so we have to be sure # to only pass this kwarg if the user asked for it. kwargs["autoescape"] = settings["autoescape"]
---------------------------------------------------------------------------------------------------------------------------------------------------------
嗯,默认的行为就是这样了,如果你有特别的需求,可以自定义一个Application,通过继承默认的类Application。还是来自blog的例子:
class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", HomeHandler), (r"/archive", ArchiveHandler), (r"/feed", FeedHandler), (r"/entry/([^/]+)", EntryHandler), (r"/compose", ComposeHandler), (r"/auth/login", AuthLoginHandler), (r"/auth/logout", AuthLogoutHandler), ] settings = dict( blog_title=u"Tornado Blog", template_path=os.path.join(os.path.dirname(__file__), "templates"), static_path=os.path.join(os.path.dirname(__file__), "static"), ui_modules={"Entry": EntryModule}, xsrf_cookies=True, cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__", login_url="/auth/login", autoescape=None, ) tornado.web.Application.__init__(self, handlers, **settings) # Have one global connection to the blog DB across all handlers self.db = tornado.database.Connection( host=options.mysql_host, database=options.mysql_database, user=options.mysql_user, password=options.mysql_password)
上面高亮的部分,或者会被tornado其他的地方用到 (比如xsrf_cookies),或者会被用户自己的代码用到(比如blog_title),反正构造函数不管就是了。
构造函数了解了,然后顺便看看Application类的其他方法们:
- listen。根据给出的参数启动一个HTTPServer,关于这个方法,有两个注意事项:1. For advanced uses (e.g. preforking), do not use this method; create an HTTPServer and call its bind/start methods directly. 2. Note that after calling this method you still need to call IOLoop.instance().start() to start the server.
- add_handler。如果你在Application初始化之后后悔了,想要添加其他的路由映射关系,那就调用这个方法吧!根据上面所说的,含有wildcard字符的路由映射会拥有较低的优先级(其实Application会维护一个handler的列表,每次在规则表中查找映射的时候总是从第一个开始依次遍历,所谓低优先级,就是处在列表尾端而已)
- add_transform。Again,不知道干啥地。。。
- _get_host_handlers。顾名思义,如果目有找到,返回None。
- _load_ui_methods。貌似是从一个或一些UIModule里面把所有的uimethod导入到Application类实例中的self.ui_methods里面。不过不知道意义何在。。。
- _load_ui_modules。把一个或一些UIModule备份在Application类实例中的self.ui_modules里面。也不知道干啥用。。。收藏癖?
- __call__。这个好,在第一个提到的listen方法里面,会把当前application实例(调用listen的那个)作为参数传入HttpServer,既然Application知道的太多,HttpServer显然会把它往死了用。基本上HttpServer自己只管在门口拉客放风,客人来了具体怎么找到对客人胃口的小姐那就是Application这个老鹞的事情了(主要逻辑就是__call__函数中)。。。。而具体办事,老鹞是不亲自上阵的(客人想也不行!),客人满意不满意完全依赖于各位小姐(各个Handler)自己的本事。。。
- reverse_url。不懂
- log_request。这还用说么?我觉得还是要说。主要是,开发者可以通过传入Application的Settings来自定义log方法;否则使用默认的logging。
相关推荐
return tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 这个应用会在本地8888端口监听,...
如果你还没有安装,可以通过`pip install webpy`命令进行安装。 接着,创建一个Python文件,例如`app.py`,并在其中定义URL映射、处理函数和模板。以下是一个简单的示例: ```python import web urls = ( '/', '...
application.listen(8000) tornado.ioloop.IOLoop.current().start() ``` 这个简单的应用会在访问 `http://your_server_ip:8000/` 时返回 "Hello, world"。 ### 运行Tornado应用 保存文件后,在终端中执行以下...
设置您无需更改任何内容即可使用您自己的 Django 项目运行它,但是run_tornado.py这一行: os . environ [ 'DJANGO_SETTINGS_MODULE' ] = 'demosite.settings' # TODO: edit this DJANGO_SETTINGS_MODULE应该指向 ...
可能包含`tornado.web.Application`的创建,以及`tornado.ioloop.IOLoop`的启动。 2. **处理器类**(如`handlers.py`):这些是处理特定URL请求的类,继承自`tornado.web.RequestHandler`。每个类通常有一个`get`或...
application.listen(8000) IOLoop.current().start() ``` 这个应用将监听8000端口,并在访问根URL时返回"Hello, world!"。 **3.2. Supervisor配置** 在Supervisor的配置文件中,为你的Tornado应用添加一个配置段...
本实例将探讨如何使用Tornado框架来实现一个简单的Todo应用,它是基于Web.py的Todo应用的改写版本。 首先,我们需要了解Tornado的基础架构。Tornado的核心组件包括`HTTPServer`、`RequestHandler`和`Application`。...
Tornado 是一个强大的 Python Web 框架,它以其异步非阻塞 I/O 模型而著名,特别适合处理高并发场景。本项目结构针对的是一个基础的 Tornado 应用,旨在帮助初学者理解如何组织 Tornado 项目的文件和目录。下面将...
Tornado使用`tornado.web.Application`来创建应用实例,并通过`add_handlers`方法添加路由。每个处理程序类继承自`tornado.web.RequestHandler`,并在其中定义`get`、`post`等方法来处理HTTP请求。 3. **数据库操作...
return tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 运行这个文件,然后在浏览器访问...
return tornado.web.Application([ (r"/ws", WebSocketHandler), ]) if __name__ == "__main__": app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 2. **AIOHTTP WebSocket*...
2. **TornadoExecutor**:与Tornado Web框架无缝配合,支持异步操作和事件循环。 3. **ThreadPoolExecutorPlus**:增强版的线程池,提供了额外的控制和监控功能,如超时处理和取消任务。 4. **...
**正文** ...总的来说,"Tornado实战之一"将引导你逐步进入Tornado的世界,让你理解其核心概念和用法,为更复杂的Web应用开发打下坚实基础。通过实践,你将学会如何构建高效、响应迅速的Python Web服务。
application.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 在这个例子中,当客户端连接到`/ws`路径时,`open()`方法会被调用。客户端发送的消息会被`on_message()`处理,并通过`write_message()`...
`config` 目录用来存储全局的配置文件,如 `application.py`,其中包含了 Tornado 应用实例的初始化配置,如路由设置、中间件等。 ### 4. `static` 目录 `static` 目录存储所有静态资源,如 CSS、JavaScript 文件...
- 在Tornado中,Web服务器通常基于`Application`和`RequestHandler`。你需要定义路由和对应的处理器,比如创建一个`IndexHandler`来处理根路径请求,然后在`Application`中注册这个处理器。 - 如果需要与Socket...
from tornado.web import Application, RequestHandler from tornado.eventsource import EventSourceHandler class SSEHandler(EventSourceHandler): def data_received(self, data): # 假设data是新接收到的...
from tornado.web import Application from tornado.websocket import WebSocketHandler from terminado import ManagedTerminal class TerminalHandler(WebSocketHandler): async def open(self): self.term = ...
return tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": parse_command_line() app = make_app() app.listen(options.port) tornado.ioloop.IOLoop.current().start() ``` ...