内容简介:本章,我将和大家一起看看如果你有以下的需求:
Sanic
是一个可以使用 async/await
语法编写项目的异步非阻塞框架,它写法类似于 Flask
,但使用了异步特性,而且还使用 uvloop
作为事件循环,其底层使用的是 libuv
,从而使 Sanic
的速度优势更加明显。
本章,我将和大家一起看看 Sanic
里面的运行机制是怎样的,它的 RouterBlueprint
等是如何实现的。
如果你有以下的需求:
-
想深入了解Sanic,迫切想知道它的运行机制
-
直接阅读源码,做一些定制
-
学习
将Sanic-0.1.2阅读完后的一些建议,我觉得你应该有以下基础再阅读源码才会理解地比较好:
-
理解装饰器,见附录
-
理解协程
Sanic-0.1.2 的核心文件如下:
通过运行下面的示例,这些文件都会被我们看到它的作用,拭目以待吧,为了方便诸位的理解,我已将我注解的一份 Sanic
代码上传到了 github
,见sanic_annotation。
simple_server.py
让我们从simple_server开始吧,代码如下:
或许你直接把sanic_annotation项目直接clone到本地比较方便调试+理解:
那么,现在一切准备就绪,开始阅读吧。
前两行代码导入包:
-
Sanic:构建一个 Sanic 服务必须要实例化的类 -
json:以json格式返回结果,实际上是HTTPResponse类,根据实例化参数content_type的不同,构建不同的实例,如: -
text:content_type="text/plain; charset=utf-8" -
html:content_type="text/html; charset=utf-8"
实例化一个 Sanic
对象, app=Sanic(__name__)
,可见sanic.py,我已经在这个文件里面做了一些注释,这里也详细说下 Sanic
类:
-
route():装饰器,构建uri和视图函数的映射关系,调用Router().add()方法
-
exception():装饰器,和上面差不多,不过针对的是错误处理类Handler
-
middleware():装饰器,针对中间件
-
register_blueprint():注册视图的函数,接受第一个参数是视图类
blueprint,再调用该类下的register方法实现将此蓝图下的route、exception、middleware统一注册到app.route、app.exception、app.exception -
handle_request():这是一个很重要的异步函数,当服务启动后,如果客户端发来一个有效的请求,会自动执行
on_message_complete函数,该函数的目的是异步调用handle_request函数,handle_request函数会回调write_response函数,write_response接受的参数是此uri请求对应的视图函数,比如上面demo中,如果客户端请求'/',那么这里write_response就会接受json({"test":True}),然后进一步处理,再返回给客户端 -
run():Sanic服务的启动函数,必须执行,实际上会继续调用
server.serve函数,详情下面会详细讲 -
stop():终止服务
其实上面这部分介绍已经讲了Sanic基本的运行逻辑,如果你理解了,那下面的讲解对你来说是轻轻松松,如果不怎么明白,也不要紧,这是只是一个大体的介绍,跟着步骤来,也很容易理解,继续看代码:
app.route
,上面介绍过,随着Sanic服务的启动而启动,可定义参数 uri,methods
目的是为 url
的 path
和视图函数对应起来,构建一对映射关系,本例中 Sanic.router
类下的 Router.routes=[]
会增加一个名为 Route
的 namedtuple
,如下:
看到没, uri'/'
和视图函数 test
对应起来了,如果客户端请求 '/'
,当服务器监听到这个请求的时候, handle_request
可以通过参数中的 request.url
来找到视图函数 test
并且执行,随即生成视图返回
那么这里 write_response
就会接受视图函数test返回的 json({"test":True})
说下 Router
类,这个类的目的就是添加和获取路由对应的视图函数,把它想象成 dict
或许更容易理解:
-
add(self, uri, methods, handler):添加一个映射关系到self.routes
-
get(self, request):获取request.url对应的视图函数
最后一行, app.run(host="0.0.0.0",port=8000)
,Sanic 下的 run
函数,启动一个 http server
,主要是启动 run
里面的 serve
函数,参数如下:
让我们将目光投向server.py,这也是Sanic框架的核心代码:
-
serve():里面会创建一个TCP服务的协程,然后通过
loop.run_forever()运行这个事件循环,以便接收客户端请求以及处理相关事件,每当一个新的客户端建立连接服务就会创建一个新的Protocol实例,接受请求与返回响应离不开其中的HttpProtocol,里面的函数支持接受数据、处理数据、执行视图函数、构建响应数据并返回给客户端 -
HttpProtocol:
asyncio.Protocol的子类,用来处理与客户端的通信,我在server.py里写了对应的注释
至此,Sanic 服务启动了
不要小看这一个小小的demo,执行一下,竟然涉及到下面这么多个文件,让我们总结一下:
-
sanic.py
-
server.py
-
router.py
-
request.py
-
response.py
-
exceptions.py
-
config.py
-
log.py
除去 __init__.py
, Sanic
项目一共就10个文件,这个小demo不显山不露水地竟然用到了8个,虽然其中几个没有怎么用到,但也足够说明,你如果理解了这个demo, Sanic
的运行逻辑以及框架代码你已经了解地很深入了
blueprints.py
这个例子看完,我们就能轻易地明白什么是 blueprints
,以及 blueprints
的运行方式,代码如下:
让我们从这两行开始:
显然, blueprint
以及 blueprint2
是 Blueprint
根据不同的参数生成的不同的实例对象,接下来要干嘛?没错,分析blueprints.py:
-
BlueprintSetup:蓝图注册类
-
add_route:添加路由到app
-
add_exception:添加对应抛出的错误到app
-
add_middleware:添加中间件到app
-
Blueprint:蓝图类,接收两个参数:name(蓝图名称) url_prefix 该蓝图的url前缀
-
route:路由装饰器,将会生成一个匿名函数到self.deferred_functions列表里稍后一起处理注册到app里
-
middleware:同上
-
exception:同上
-
record:注册一个回调函数到self.deferred_functions列表里面,
-
make setup state:实例化BlueprintSetup
-
register:注册视图,实际就是注册route、middleware、exception到app,此时会利用make setup state返回的BlueprintSetup示例进行对于的add_ * 一系列操作,相当于Sanic().route()效果
请看下 route
和 register
函数,然后再看下面的代码:
怎么样,现在来看,是不是很轻松,这一行 app.run(host="0.0.0.0",port=8000,debug=True)
服务启动代码不用多说吧?
总结
看到这里,相信你已经完全理解了 Sanic
的运行机制,虽然还有 middleware&exception
的注册以及调用机制没讲,但这和 route
的运行机制一样,如果你懂了 route
那么这两个也很简单。
如果诸位一遍没怎么看明白,这里我建议可以多看几遍,多结合编辑器 Debug
下源码,坚持下来,会发下 Sanic
真的很简单,当然,这只是第一个小版本的 Sanic
,和目前的版本相比,不论是代码结构的复杂程度以及功能对比,都有很大差距,毕竟, Sanic
一直在开源工作者的努力下,慢慢成长。
本人技术微末,若有错误,请指出,不胜感激.
-
注解地址:sanic_annotation - 点击阅读原文
-
博客地址:http://blog.howie6879.cn/post/31/
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 【Java集合源码剖析】ArrayList源码剖析
- Java集合源码剖析:TreeMap源码剖析
- 我的源码阅读之路:redux源码剖析
- ThreadLocal源码深度剖析
- SharedPreferences源码剖析
- Volley源码剖析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Paradigms of Artificial Intelligence Programming
Peter Norvig / Morgan Kaufmann / 1991-10-01 / USD 77.95
Paradigms of AI Programming is the first text to teach advanced Common Lisp techniques in the context of building major AI systems. By reconstructing authentic, complex AI programs using state-of-the-......一起来看看 《Paradigms of Artificial Intelligence Programming》 这本书的介绍吧!