WSGI

引言

瞭解了HTTP協議和HTML文檔,咱們其實就明白了一個Web應用的本質就是:html

1.瀏覽器發送一個HTTP請求;

2.服務器收到請求,生成一個HTML文檔;

3.服務器把HTML文檔做爲HTTP響應的Body發送給瀏覽器;

4.瀏覽器收到HTTP響應,從HTTP Body取出HTML文檔並顯示。

  

因此,最簡單的Web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。Apache、Nginx、Lighttpd等這些常見的靜態服務器就是幹這件事情的。python

 

若是要動態生成HTML,就須要把上述步驟本身來實現。不過,接受HTTP請求、解析HTTP請求、發送HTTP響應都是苦力活,若是咱們本身來寫這些底層代碼,還沒開始寫動態HTML呢,就得花個把月去讀HTTP規範。web

正確的作法是底層代碼由專門的服務器軟件實現,咱們用Python專一於生成HTML文檔。由於咱們不但願接觸到TCP鏈接、HTTP原始請求和響應格式,因此,須要一個統一的接口,讓咱們專心用Python編寫Web業務。瀏覽器

這個接口就是WSGI:Web Server Gateway Interface。bash

 

一:WSGI介紹

1:介紹

WSGI是Web 服務器(uWSGI)與 Web 應用程序或應用框架(Django)之間的一種低級別的接口

 

WSGI:全稱是Web Server Gateway InterfaceWSGI不是服務器,python模塊,框架,API或者任何軟件,只是一種規範,描述web server如何與web application通訊的規範。serverapplication的規範在PEP 3333中有具體描述。要實現WSGI協議,必須同時實現web server和web application,當前運行在WSGI協議之上的web框架有Torando,Flask,Django服務器

uwsgi:WSGI同樣是一種通訊協議,是uWSGI服務器的獨佔協議,用於定義傳輸信息的類型(type of information),每個uwsgi packet前4byte爲傳輸信息類型的描述,與WSGI協議是兩種東西,聽說該協議是fcgi協議的10倍快。app

uWSGI:是一個web服務器,實現了WSGI協議、uwsgi協議、http協議等。框架

 

WSGI協議主要包括serverapplication兩部分:webapp

WSGI server負責從客戶端接收請求,將request轉發給application,將application返回的response返回給客戶端;
WSGI application接收由server轉發的request,處理請求,並將處理結果返回給server。application中能夠包括多個棧式的中間件(middlewares),這些中間件須要同時實現server與application,所以能夠在WSGI服務器與WSGI應用之間起調節做用:對服務器來講,中間件扮演應用程序,對應用程序來講,中間件扮演服務器。

 

 

WSGI協議實際上是定義了一種serverapplication解耦的規範,便可以有多個實現WSGI server的服務器,也能夠有多個實現WSGI application的框架,那麼就能夠選擇任意的server和application組合實現本身的web應用。例如uWSGIGunicorn都是實現了WSGI server協議的服務器,DjangoFlask是實現了WSGI application協議的web框架,能夠根據項目實際狀況搭配使用函數

 

 

2:WSGI規範

WSGI規範以下:

  • 服務器的請求處理程序中要調用符合WSGI規範的網關接口;
  • 網關接口調用應用程序,而且要定義start_response(status, headers)函數,用於返回響應;
  • 應用程序中實現一個函數或者一個可調用對象webapp(environ, start_response)。其中environ是環境設置的字典,由服務器和WSGI網關接口設置,start_response是由網關接口定義的函數。

在Python標準庫中,wsgiref包就是符合WSGI標準的Web服務實現。後面簡單對wsgiref包進行介紹,以此來對符合WSGI標準的Web服務的實現過程進行梳理。

 

 

 

二:實現WSGI

 

WSGI接口定義很是簡單,它只要求Web開發者實現一個函數,就能夠響應HTTP請求。咱們來看一個最簡單的Web版本的「Hello, web!」:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, web!</h1>']

 

 

而後,再編寫一個server.py,負責啓動WSGI服務器,加載application()函數:

# server.py
# 從wsgiref模塊導入:
from wsgiref.simple_server import make_server
# 導入咱們本身編寫的application函數:
from hello import application

# 建立一個服務器,IP地址爲空,端口是8000,處理函數是application:
httpd = make_server('', 8000, application)
print('Serving HTTP on port 8000...')
# 開始監聽HTTP請求:
httpd.serve_forever()

 

 

 

小結

不管多麼複雜的Web應用程序,入口都是一個WSGI處理函數。HTTP請求的全部輸入信息均可以經過environ得到,HTTP響應的輸出均可以經過start_response()加上函數返回值做爲Body。

複雜的Web應用程序,光靠一個WSGI函數來處理仍是太底層了,咱們須要在WSGI之上再抽象出Web框架,進一步簡化Web開發。

 

 


 

參考資料

http://python.jobbole.com/88637/

http://python.jobbole.com/88653/

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432012393132788f71e0edad4676a3f76ac7776f3a16000

相關文章
相關標籤/搜索