WSGI基础知识(转)

add by zhj: WSGI全称Web Server Gateway Interface,即Web网关接口。其实它并非OSI七层协议中的协议,它就是一个接口(即函数)而已,而WSGI规定了该接口的输入,输出等,其中输入是指Python应用程序服务器调用接口时提供的实参包含哪些数据,输出是指接口必须返回哪些参数给接口调用者(即Python应用程序服务器)。应用程序服务器会直接调用Web框架的WSGI接口,而不是经过socket来调用。说白了,WSGI就是接口的规范而已python

WSGI基础知识

翻译自Basics of WSGIhttp://agiliq.com/blog/2013/07/basics-wsgi/
译文 WSGI基础知识git

在这篇文章里,咱们将会写一个web app,这个app它会服务一些url。咱们将不会使用任何Python框架来写它。咱们只是去说明一下这些机制的背后原理。github

在开始写这个web app以前,咱们先来澄清几个下文将要用到的术语。web

  • Web服务器(Web Server): 当咱们说Web 服务器时,咱们指的是软件,而不是那些存储你代码的硬件机器。这个服务器会接收从客户端(Web浏览器)发送过来的请求并返回一个响应(response)。Web服务器自己并不建立响应,它只负责返回响应。因此,Web服务器就须要同Web应用程序交流,由于Web应用程序它能产生响应。浏览器

  • Web应用程序(Web Application):Web服务器从它这里拿到响应。Web Application的职责就是根据url来建立响应并将响应传回给Web服务器。而后Web服务器就只是返回这个响应到客户端而已。服务器

  • WSGI: WSGI是一个接口,它只是一份规范或者说是一系列的规则。WSIG不是一个软件。架构

WSGI会引发人们的注意是由于Web服务器须要跟Web应用程序通讯。WSGI规定了Web应用程序和Web服务器双方必须实现的规则,以便让它们之间可以互相交互。这么说吧,一个符合WSGI规范的服务器就能够跟一个符合WSGI规范的Web应用程序通讯。app

在WSGI架构里,WSGI应用程序必须是一个可调用者(callable),而且这个可调用者(callable)必须被传递给Web服务器,这样无论何时,只要Web服务器接收到客户端的一个请求,它就能随时调用Web应用程序。框架

想要了解更多关于为何WSGI会得以出现的缘由,请参照 WSGI的维基百科socket

如今开始写咱们的Web应用程序。你暂时只须要所有拷贝下面的代码便可,咱们稍后会对每一行代码作详细解释以便清楚地知道它们都作了什么。

#web_application.py
from wsgiref.simple_server import make_server

def application(environ, start_response):
    path = environ.get('PATH_INFO')
    if path == '/':
        response_body = "Index"
    else:
        response_body = "Hello"
    status = "200 OK"
    response_headers = [("Content-Length", str(len(response_body)))]
    start_response(status, response_headers)
    return [response_body]

httpd = make_server(
    '127.0.0.1', 8051, application)

httpd.serve_forever()

这个脚本能够经过运行命令python web_application.py来执行,接着你能够在浏览器中访问连接http://127.0.0.1:8051/http://127.0.0.1:8051/abcd。你将看到第一个页面会返回Index,而第二个页面返回Hello。

如今,咱们来逐句分析下代码。

  • Python提供了一个方法叫作make_server。咱们能够用它来建立一个遵循WSGI规范的基于Python的Web服务器。
  • 咱们建立了一个callable叫作application。你能够认为这个callable就是上文所说的Web应用程序。
  • make_server()方法建立了一个遵循WSGI规范的web服务器。这里的httpd就是Web服务器。
  • make_server()的前两个参数指定了主机(host)以及Web服务器监听请求的端口(port)。
  • make_server()的第三个参数是Web应用程序,Web服务器将利用这个参数来获取响应。
  • 代码的最后一行经过serve_forever来启动Web服务器。

无论何时,只要有请求进来,运行在8051端口的Web服务器就会去调用Web应用程序,在咱们这个例子里,Web应用程序就是callable application.

下面是关于Web应用程序代码的细节。

  • 为了能和WSGI的Web服务器交互,Web应用程序一样也必须遵循WSGI规范。
  • 服务器调用它时须要两个参数。因此,它必须接收两个参数,这是Web应用程序遵循WSGI规范的第一个条件。
  • 传给它的第一个参数是包含了许多关于请求(request)信息的一个变量。在咱们这个例子里,咱们用它来读取请求的路径。
  • 传给它的第二个参数是一个callable。应用程序必须利用这个callable来通知服务器关于响应的状态以及设定各类报头(headers)。这是Web应用程序遵循WSGI规范的第二个条件。
  • 咱们的应用程序知足了遵循WSGI规范所要求的两个条件。
  • 最后,应用程序返回一个响应给WSGI服务器。
  • 而后,服务器最终会转发这个响应给客户端。

编辑:

我以前在application的代码里忽略了一件事,defnull童鞋在reddit上指出了个人错误。

application的最后一行不能返回response_body,正确的状况是它应该返回[response_body]。缘由是:

  • WSGI服务器指望从应用程序返回一个iterable而后它会将这个iterable的每个元素以一种无缓冲的方式发送给客户端。
  • 若是咱们坚持返回response_body,那么response_body是一个string同时也是一个iterable,这样的话咱们的代码确实还能正常工做不会报错。可是同时也使得response_body中的内容将会被一个字符一个字符地传递。
  • 然而,若是咱们返回的是[response_body], 在这里,这个iterable是一个list, 这个list只有惟一一个元素即response_body字符串。这样,在咱们这个例子里,整个response_body就只须要被传递一次。
  • 这就是为何咱们应该返回[response_body]而不是response_body。上面的代码我已经改过来了。

你应该读读这篇WSGI来了解更多关于WSGI。

译者注

  • 更新时间:2014-11-28
  • 本人翻译的初衷是为了自身学习和记录,翻译很差的地方,还望读者见谅.
相关文章
相关标签/搜索