Wsgi研究

Wsgi研究转载自 http blog kenshinx me blog wsgi research wsgi 是一个搞 web 开发的 pythoner 必须了解的内容 之前也零散的看过一些文章 但总感觉好多概念很模糊 这几天抽空又把相关内容好好整理了一下 把笔记贴出来 一些只言片语也许对某些正在研究这个的人有所帮助 wsgi 是一个 web 组件的接口规范 wsgi 将 web 组件分为三类

//转载自http://blog.kenshinx.me/blog/wsgi-research/

Wsgi研究

从上图可以看出来,wsgi基本处理模式为 : WSGI Server -> (WSGI Middleware)*-> WSGI Application 。

下面分别来看这三个组件

WSGI Server/gateway

Wsgi研究

通过这个图可以看出来wsgi server 基本工作流程

  1. 服务器创建socket,监听端口,等待客户端连接。
  2. 当有请求来时,服务器解析客户端信息放到环境变量environ中,并调用绑定的handler来处理请求。
  3. handler解析这个http请求,将请求信息例如method,path等放到environ中。
  4. wsgi handler再将一些服务器端信息也放到environ中,最后服务器信息,客户端信息,本次请求信息全部都保存到了环境变量environ中。
  5. wsgi handler 调用注册的wsgi app,并将environ和回调函数传给wsgi app
  6. wsgi app 将reponse header/status/body 回传给wsgi handler
  7. 最终handler还是通过socket将response信息塞回给客户端。

WSGI Application

wsgi application就是一个普通的callable对象,当有请求到来时,wsgi server会调用这个wsgi app。这个对象接收两个参数,通常为environ,start_response。environ就像前面介绍的,可以理解为环境变量,跟一次请求相关的所有信息都保存在了这个环境变量中,包括服务器信息,客户端信息,请求信息。start_response是一个callback函数,wsgi application通过调用start_response,将response headers/status 返回给wsgi server。此外这个wsgi app会return 一个iterator对象 ,这个iterator就是response body。这么空讲感觉很虚,对着下面这个简单的例子看就明白很多了。

下面这个例子是一个最简单的wsgi app,引自http://www.python.org/dev/peps/pep-3333/

def simple_app(environ, start_response): status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return [u"This is hello wsgi app".encode('utf8')] 

我们再用wsgiref 作为wsgi server ,然后调用这个wsgi app,就能直观看到一次request,response的效果,简单修改代码如下:

from wsgiref.simple_server import make_server def simple_app(environ, start_response): status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return [u"This is hello wsgi app".encode('utf8')] httpd = make_server('', 8000, simple_app) print "Serving on port 8000..." httpd.serve_forever() 

访问http://127.0.0.1:8000 就能看到效果了。

此外,上面讲到了wsgi app只要是一个callable对象就可以了,因此不一定要是函数,一个实现了call方法的实例也可以,示例代码如下:

from wsgiref.simple_server import make_server class AppClass: def __call__(self,environ, start_response): status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return ["hello world!"] app = AppClass() httpd = make_server('', 8000, app) print "Serving on port 8000..." httpd.serve_forever() 

WSGI MiddleWare

上面的application看起来没什么意思,感觉没有太大用,但加上一层层的middleware包装之后就不一样了。一堆文字解释可能还没有一个demo更容易说明白,我写了一个简单Dispatcher Middleware,用来实现URL 路由:

from wsgiref.simple_server import make_server

URL_PATTERNS= (
    ('hi/','say_hi'),
    ('hello/','say_hello'),
    )

class Dispatcher(object):

    def _match(self,path):
        path = path.split('/')[1]
        for url,app in URL_PATTERNS:
            if path in url:
                return app

    def __call__(self,environ, start_response):
        path = environ.get('PATH_INFO','/')
        app = self._match(path)
        if app :
            app = globals()[app]
            return app(environ, start_response)
        else:
            start_response("404 NOT FOUND",[('Content-type', 'text/plain')])
            return ["Page dose not exists!"]

def say_hi(environ, start_response):
    start_response("200 OK",[('Content-type', 'text/html')])
    return ["kenshin say hi to you!"]

def say_hello(environ, start_response):
    start_response("200 OK",[('Content-type', 'text/html')])
    return ["kenshin say hello to you!"]

app = Dispatcher()

httpd = make_server('', 8000, app)
print "Serving on port 8000..."
httpd.serve_forever()

上面的例子可以看出来,middleware 包装之后,一个简单wsgi app就有了URL dispatch功能。然后我还可以在这个app外面再加上其它的middleware来包装它,例如加一个权限认证的middleware:

class Auth(object): def __init__(self,app): self.app = app def __call__(self,environ, start_response): #TODO return self.app(environ, start_response) app = Dispatcher() auth_app = Auth(app) httpd = make_server('', 8000, auth_app) print "Serving on port 8000..." httpd.serve_forever() 

经过这些middleware的包装,已经有点框架的感觉了。其实基于wsgi的框架,例如paste,pylons就是这样通过一层层middleware组合起来的。只是一个成熟的框架,这样的middleware会有很多,例如:

def configure(app): return ErrorHandlerMiddleware( SessionMiddleware( IdentificationMiddleware( AuthenticationMiddleware( UrlParserMiddleware(app)))))) 

只要这些Middleware符合wsgi规范,甚至还可以在各个框架之间组合重用。例如pylons的认证Middleware可以直接被TurboGears拿去使用。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233572.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 向量的夹角余弦公式_向量空间模型(VSM)的余弦定理公式(用余弦定理来表示向量之间的相似度)…[通俗易懂]

    向量的夹角余弦公式_向量空间模型(VSM)的余弦定理公式(用余弦定理来表示向量之间的相似度)…[通俗易懂]相信很多学习向量空间模型(VectorSpaceModel)的人都会被其中的余弦定理公式所迷惑..因为一看到余弦定理,肯定会先想起初中时的那条最简单的公式cosA=a/c(邻边比斜边),见下图:但是,初中那条公式是只适用于直角三角形的,而在非直角三角形中,余弦定理的公式是:cosA=(c2+b2-a2)/2bc不过这条公式也和向量空间模型中的余弦定理公式不沾边,迷惑..引用吴军老师的数…

    2025年7月9日
    0
  • Pytest(1)安装与入门「建议收藏」

    Pytest(1)安装与入门「建议收藏」pytest介绍pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高。根据pytest的官方网站介绍,它

    2022年7月30日
    3
  • win10开始键没反应解决方法「建议收藏」

    win10开始键没反应解决方法「建议收藏」win10开始键没反应解决方法具体方法如下:1、打开运行窗口。windows7系统:通过“开始”菜单进入。点击“开始”菜单,从打开的菜单中依次点击“所有程序”>“附件”>“运行”来打开“运行”窗口。windows10系统:右击屏幕左下角win标志,在弹出的菜单中找到“运行”,点击进入运行窗口2、在搜索窗口输入“regedit”,打开注册表编辑器。3、在在注册表“HKEY_CLASSES_ROOT”主键下找到“lnkfile”字符串值项。打开它。4、在右侧右击它,会出现一个菜单

    2022年5月4日
    43
  • linux环境下将某个目录下的文件复制或者移动到另一个目录下[通俗易懂]

    linux环境下将某个目录下的文件复制或者移动到另一个目录下[通俗易懂]1、将一个文件夹下的所有内容复制到另一个文件夹下cp-r/home/packageA/*/home/cp/packageB/或cp-r/home/packageA/./home/cp/packageB/这两种方法效果是一样的。2、将一个文件夹复制到另一个文件夹下cp-r/home/packageA/home/packageB运行命令之后packageB文件夹下就有packageA文件夹了。3、删除一个文件夹及其下面的所有文件rm-r/home/packag

    2022年8月23日
    3
  • Pytest(6)重复运行用例pytest-repeat「建议收藏」

    Pytest(6)重复运行用例pytest-repeat「建议收藏」前言平常在做功能测试的时候,经常会遇到某个模块不稳定,偶然会出现一些bug,对于这种问题我们会针对此用例反复执行多次,最终复现出问题来。自动化运行用例时候,也会出现偶然的bug,可以针对单个用例,

    2022年7月29日
    4
  • Codeforces 85D Sum of Medians(线段树)[通俗易懂]

    Codeforces 85D Sum of Medians(线段树)

    2022年1月25日
    56

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号