仿寫以WSGI為標準的web框架體
1 動態web框架
1.1 web框架要和web服務器軟件分開(如MVC)
1.2 web框架要和web服務器有良好的交互通信(python為自身的web框架制定了WSGI標準)
1.3 web框架要和數據庫有良好的讀寫通信方法
2 關於WSGI標準
WSGI將Web服務分成兩個部分:服務器和應用程序。WGSI服務器只負責與網絡相關的兩件事:接收瀏覽器的 HTTP請求、向瀏覽器發送HTTP應答;而對HTTP請求的具體處理邏輯,則通過調用WSGI應用程序進行。
2.1 一個個簡單wsgi實現應用
from wsgiref.simple_server import make_serverdef wsgi_app(environ, start_response): status = ‘200 ok‘ response_header = [(‘Content_Type‘, ‘text/html‘)] start_response(status, response_headers) return ‘there is a wsgi app!‘ httpd = make_server(‘0.0.0.0‘,80,wsgi_app) httpd.serve_forever()
environ是一個包含全部HTTP請求信息的字典/Dict,由WSGI服務器解包HTTP請求生成。
2.2 WSGI模型特點:
1.在web框架模塊,以上面的栗子為例,web服務器軟件會向web框架傳遞一個列表(environ)和一個函數(函數體在web服務器軟件中實現)的引用(start_response),然後web框架要實現一個app函數,並將 "一個列表"和"一個函數的引用",作為兩個參數;
2.傳遞過來的列表內部存儲了N個元組,這些元組包含了web服務器接收到的客戶端瀏覽器的請求信息, 傳遞過來的函數參數的引用,可以用來返回請求資源的狀態反饋(如果請求的資源可以訪問,就會返回200,如果資源無法訪問,就返回404或502之類的錯誤;
3.傳遞過來的函數引用的調用比return更靠前,這樣可以在返回正式的網頁之前的這段時間,讓web服務器軟件做好接收數據的準備;(其實可以將函數的引用作為web框架與web服務器軟件傳遞數據的的一種快捷方式);
所以web服務器框架至少要實現三個功能
1.創建 包含客戶端請求頭消息的列表(作為第一個參數傳遞);
2.創建一個可以解析返回狀態信息的函數(作為第二個參數傳遞);
3.接收web框架內app函數返回的body,並將body與作為第二個參數的引用的函數的返回狀態值組合,一同發送給客戶端瀏覽器
3 具體實現
3.1 首先需要實現一個WISG的類作為server
class WSGI(object): def __init__(self, port, app): 裏面主要是初始化的socket定義 .... # 獲取web框架的引用 self.app = app pass # 啟動服務器對象入口函數 def run_forever(self): self.create_new_socket() pass def create_new_socket(self): while True: ... # 對請求進行相應的處理 self.deal_accept_data(new_client_socket) def deal_accept_date(self, new_client_socket): # 接收數據 recv_data = new_client_socket.recv(1024) # 將接收的數據轉換為列表 recv_data_list = recv_data.splitlines() 獲取請求頭 request_header = recv_data_list[0] # 該方法就是獲取請求頭中.../.../...html,用於app處理 # GET /index.html HTTP/1.1 html_name = get_html(request_header) # 進入動態app處理階段 # 獲取web框架並且返回數據 #創建一個字典,用於存儲請求的參數 enverion = dict() enverion[‘PATH_INFO‘] = html_name # 啟動web框架進行處理, 返回response的header和body dynamic_content = self.app(enverion, start_response) #發送和關閉 new_client_socket.send(dynamic_content) new_client_socket.close() def main(): # 導入web框架的app app = __import__(file_name) # 啟動web服務器 web_server = WSGI(port, app) web_server.run_forever()
3.2 按照wsgi標準實現的web框架
def app(enverion, start_response): # response是可以根據需求所改變的,可以根據environ的參數 # 設置狀態碼 status = ‘200 ok‘ # 設置返回的網頁類型 response_headers = [(‘Content_Type‘, ‘text/html‘)] # 向web框架中定義的函數start_response中傳入頭部信息 # 先處理response的headers, 再對content進行返回 start_response(status, response_headers) # 根據匹配的路徑返回需要的response的body path_name = enverion[‘PATH_INFO] content = process_path(path_name) return content def process_path(path_name) 尋找處理的函數 v_func = match_path(path_name) content = v_func.return_result() return content
仿寫以WSGI為標準的web框架體