WSGI(Web Server Gateway Interface):Web服務網關接口,是Python中定義的服務器程序和應用程序之間的接口。
Web程序開發中,一般分為服務器程序和應用程序。服務器程序負責對socket服務的數據進行封裝和整理,而應用程序則負責對Web請求進行邏輯處理。
Web應用本質上也是一個socket服務器,用戶的瀏覽器就是一個socket客戶端。
我們先用socket編程實現一個簡單的Web服務器:
import socket  def handle_request(client):   buf = client.recv(1024)   print(buf)   msg = "HTTP/1.1 200 OK/r/n/r/n" #HTTP頭信息   client.send(('%s' % msg).encode())   msg = "Hello, World!"   client.send(('%s' % msg).encode())  def main():   ip_port = ("localhost", 8000)   sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   sock.bind(ip_port)   sock.listen(5)    while True:     conn, addr = sock.accept()     handle_request(conn)     conn.close()  if __name__ == "__main__":   main() 上述代碼中,main()函數就是服務器函數,handle_request()就是應用程序。
下面我們再用python的wsgiref模塊來實現跟上述代碼一樣的Web服務器:
from wsgiref.simple_server import make_server  def handle_request(env, res):   res("200 OK",[("Content-Type","text/html")])   body = "<h1>Hello World!</h1>"   return [body.encode("utf-8")]  if __name__ == "__main__":   httpd = make_server("",8000,handle_request)   print("Serving http on port 80000")   httpd.serve_forever() 上面兩份代碼實現的效果是一樣的,調用wsgiref模塊則明顯節省了代碼量,是整個程序更加簡潔。
wsgiref模塊封裝了socket服務端的代碼,只留下一個調用的接口,省去了程序員的麻煩,程序員可以將精力放在Web請求的邏輯處理中。
以上述的代碼為例,詳細看一下wsgiref模塊的源碼中一些關鍵的地方:
if __name__ == "__main__":   httpd = make_server("",8000,handle_request)   print("Serving http on port 80000")   httpd.serve_forever() 1、整個程序的入口為make_server()函數:
def make_server(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler): """Create a new WSGI server listening on `host` and `port` for `app`""" server = server_class((host, port), handler_class) #默認創建一個WSGIServer類 server.set_app(app) #將應用程序,即邏輯處理函數傳給類 return server
2、make_server()函數默認生成一個WSGIServer類:
class WSGIServer(HTTPServer):
class HTTPServer(socketserver.TCPServer):
class TCPServer(BaseServer):
WSGIServer,HTTPServer兩個類沒有初始化函數,調用父類的初始化函數,TCPServer類的__init__()函數拓展了BaseServer
類的__init__()函數:
新聞熱點
疑難解答