zoukankan      html  css  js  c++  java
  • 理解WSGI

    WSGI是什么?

    WSGI,全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。自从 WSGI 被开发出来以后,许多其它语言中也出现了类似接口。

    WSGI 的官方定义是,the Python Web Server Gateway Interface。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。

    WSGI 是作为 Web 服务器与 Web 应用程序或应用框架之间的一种低级别的接口,以提升可移植 Web 应用开发的共同点。WSGI 是基于现存的 CGI 标准而设计的。

    很多框架都自带了 WSGI server ,比如 Flask,webpy,Django、CherryPy等等。当然性能都不好,自带的 web server 更多的是测试用途,发布时则使用生产环境的 WSGI server或者是联合 nginx 做 uwsgi 。

    •  也就是说,WSGI就像是一座桥梁,一边连着web服务器,另一边连着用户的应用。但是呢,这个桥的功能很弱,有时候还需要别的桥来帮忙才能进行处理.

    WSGI的作用

    WSGI有两方:“服务器”或“网关”一方,以及“应用程序”或“应用框架”一方。服务方调用应用方,提供环境信息,以及一个回调函数(提供给应用程序用来将消息头传递给服务器方),并接收Web内容作为返回值。

    所谓的 WSGI中间件同时实现了API的两方,因此可以在WSGI服务和WSGI应用之间起调解作用:从WSGI服务器的角度来说,中间件扮演应用程序,而从应用程序的角度来说,中间件扮演服务器。“中间件”组件可以执行以下功能:

    • 重写环境变量后,根据目标URL,将请求消息路由到不同的应用对象。
    • 允许在一个进程中同时运行多个应用程序或应用框架。
    • 负载均衡和远程处理,通过在网络上转发请求和响应消息。
    • 进行内容后处理,例如应用XSLT样式表。

    WSGI 的设计确实参考了 Java 的 servlet。http://www.python.org/dev/peps/pep-0333/

    Python中的WSGI接口

    WSGI接口包含两方面:server/gateway 及 application/framework。
    server调用由application提供的可调用对象。
    另外在server和application之间还可能有一种称作middleware的中间件。
    可调用对象是指:函数、方法、类或者带有callable方法的实例。

    application

    函数、方法、类及带有callable方法的实例等可调用对象都可以作为the application object。
    WSGI协议要求:
    the application object接受两个参数且可以被多次调用

    这两个参数分别为:
    1.CGI式的字典;
    2.回调函数:application用来向server传递http状态码/消息/http头

    另外协议要求可调用对象必须将响应体封装成一个可迭代的strings返回。

    # the application object. 可以使用其他名字,
    # 但是在使用mod_wsgi 时必须为 "application"
    def application( environ, start_response):
    # 函数接受两个参数:
    # environ :包含有CGI 式环境变量的字典,由server负责提供内容
    # start_response:由server提供的回调函数,其作用是将状态码和响应头返回给server
     
    # 构造响应体,以可迭代字符串形式封装
      response_body = 'The request method was %s' % environ['REQUEST_METHOD']
     
    # HTTP 响应码及消息
      status = '200 OK'
     
    # 提供给客户端的响应头.
    # 封装成list of tuple pairs 的形式:
    # 格式要求:[(Header name, Header value)].
      response_headers = [('Content-Type', 'text/plain'),
                ('Content-Length', str(len(response_body)))]
     
    # 将响应码/消息及响应头通过传入的start_reponse回调函数返回给server
      start_response(status, response_headers)
     
    # 响应体作为返回值返回
    # 注意这里被封装到了list中.
      return [response_body]

    server

    从概述中可以知道,WSGI server必须要调用application,同时,从application的协议要求可知:
    1. WSGI server必须向application提供环境参数,因此,自身也必须能够获取环境参数。
    2. WSGI server接收application的返回值作为响应体。
    最简单的WSGI server为Python自带的wsgiref.simple_server
    示例如下:

    from wsgiref.simple_server import make_server
    srv = make_server('localhost', 8080, hello_world)
    srv.serve_forever()

    middleware

    middleware的概念没有appllication和server那么容易理解。
    假设一个符合application标准的可调用对象,它接受可调用对象作为参数,返回一个可调用对象的对象。
    那么对于server来说,它是一个符合标准的可调用对象,因此是application。
    而对于application来说,它可以调用application,因此是server。
    这样的可调用对象称为middleware。

    middleware的概念非常接近decorator。

    以一个路由的例子示例:

    import re
     
    # 这是一个标准的application object
    def index(environ, start_response):
      start_response('200 OK', [('Content-Type', 'text/html')])
      return ['index page']
     
    # 这是一个标准的application object
    def hello(environ, start_response):
      start_response('200 OK', [('Content-Type', 'text/html')])
      return ['hello page']
     
    # 这是一个标准的application object
    def not_found(environ, start_response):
      start_response('404 NOT FOUND', [('Content-Type', 'text/plain')])
      return ['Not Found Page']
     
    # map urls to functions
    urls = [
      (r'^$', index),
      (r'hello/?$', hello)
    ]
    # 这是一个middleware
    # 根据不同的route返回不同的application object
    def application(environ, start_response):
      path = environ.get('PATH_INFO', '').lstrip('/')
      for regex, callback in urls:
        match = re.search(regex, path)
        if match is not None:
  • 相关阅读:
    c++0.9-----c++ primer之noexcept解读
    c++0.8-----快速定位c++源码位置的小技巧
    c++0.7-----源码分析:iostate及badbit/failbit/eofbit/goodbit以及io文件的包含关系<原创>
    c++0.6-----如何在自己搭建的c++环境中使用extern变量
    c++0.5-----如何在widows下面搭建最简洁的c++环境
    c++0.4-----面向对象的三种关系(继承/复合/委托)
    c++0.3----this指针/static/namespace
    c++0.2-----基于对象的类(包含指针)
    3、静态代理模式
    2、工厂方法模式
  • 原文地址:https://www.cnblogs.com/hellojesson/p/6553999.html
Copyright © 2011-2022 走看看