什麼是Web伺服器 什麼是WSGI及具體實現例子
阿新 • • 發佈:2022-05-16
2022-03-26 18:35:03
要理解 Flask 的原始碼,必須有一定的 Python 基礎,要熟悉 decorator、magic method、iterator、generator 的概念和用法。還有一點是必須理解 WSGI,下面就講解一些和 WSGI 相關的概念以及用一些程式碼來幫助理解 WSGI。
什麼是Web伺服器
Web伺服器一般指網站伺服器,是指駐留於因特網上某種型別計算機的程式,可以處理瀏覽器等Web客戶端的請求並返回相應響應,也可以放置網站檔案,讓全世界瀏覽;可以放置資料檔案,讓全世界下載。目前最主流的三個Web伺服器是Apache、 Nginx 、IIS。
什麼是WSGI(協議規範)
Web伺服器閘道器介面(Web Server Gateway Interface),是為了讓Web伺服器與Python程式或框架能夠進行資料交流而定義的介面規範。也就是說,只要Web伺服器和Web應用都遵守WSGI協議,那麼Web伺服器和Web應用就可以隨意的組合。
WSGI應用(實現wsgi協議的例項)
根據WSGI的規定,Web應用(或被稱為WSGI應用)必須是一個可呼叫物件(callable object),且要滿足以下三個條件:
- 接受environ和start_response兩個引數
- 內部呼叫start_response函式來生成狀態碼和響應頭
- 返回一個可迭代的響應體
用函式實現一個WSGI應用
def application(environ, start_response):
"""
environ:包含了請求的所有資訊的字典。
start_response:用來發起響應的函式,引數是狀態碼、響應頭。
"""
start_response('200 OK', [('Content-Type', 'text/plain')])
yield b'Hello, World!\n'
用類實現一個WSGI應用
class AppClass:
def __init__(self, environ, start_response):
self.environ = environ
self.start_response= start_response
def __iter__(self):
self.start_response('200 OK', [('Content-Type', 'text/plain')])
yield b'Hello, World!\n'
Flask的WSGI實現
class Flask(_PackageBoundObject):
def wsgi_app(self, environ, start_response):
...
def __call__(self, environ, start_response):
"""Shortcut for :attr:`wsgi_app`."""
return self.wsgi_app(environ, start_response)
WSGI伺服器
簡單實現一個WSGI伺服器(僅用於理解)
from io import BytesIO
def call_application(app, environ):
status = None
headers = None
body = BytesIO()
def start_response(rstatus, rheaders):
nonlocal status, headers
status, headers = rstatus, rheaders
app_iter = app(environ, start_response)
try:
for data in app_iter:
assert status is not None and headers is not None, \
"start_response() was not called"
body.write(data)
finally:
if hasattr(app_iter, 'close'):
app_iter.close()
return status, headers, body.getvalue()
environ = {...}
status, headers, body = call_application(app, environ)
使用Python內建模組wsgiref的WSGI伺服器
from wsgiref.simple_server import make_server
def wsgi_app(environ, start_response):
...
server = make_server('0.0.0.0', 5000, wsgi_app)
server.serve_forever()
使用WerkZeug模組的WSGI伺服器
用flask run命令執行時,實際上是在執行Werkzeug實現的WSGI伺服器
from werkzeug.serving import run_simple
def wsgi_app(environ, start_response):
...
run_simple('0.0.0.0', 5000, wsgi_app)
參考
WEB伺服器_百度百科 (baidu.com)
Web Server Gateway Interface - Wikipedia