python程式設計——簡單Web服務框架
阿新 • • 發佈:2018-12-12
1.簡單實現web服務框架 使用協程實現併發,也可換成程序
準備檔案——index.html (見附)
說明:一下程式碼可直接複製貼上
Web_server.py
from gevent import monkey monkey.patch_all() import socket import gevent import re import application class WebServer(object): """伺服器類""" def __init__(self): """ 物件初始化 """ self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 設定埠重用 self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # 繫結埠號 self.tcp_server_socket.bind(("", 8080)) # 監聽網路,套接字由主動變為被動,最大監聽數為128 self.tcp_server_socket.listen(128) def run(self): # 接收客戶端的連線 while True: new_socket, addr = self.tcp_server_socket.accept() gevent.spawn(self.deal_request, new_socket) def deal_request(self, new_socket): # 接收客戶請求資料 request_data = new_socket.recv(1024) # 判斷資料是否存在 if not request_data: new_socket.close() return request_data_str = request_data.decode() # 獲取請求行 request_list = request_data_str.split("\r\n") request_line = request_list[0] # 獲取請求路徑 result = re.search(r"\s(.*)\s", request_line) path = result.group(1) # 判斷路徑是否存在 if not path: new_socket.close() return if path == "/": path = "/index.html" if not path.endswith(".py"): # 靜態資源(假設不是以py結尾的都是靜態資源) try: with open(path, "rb") as file: response_content = file.read() except Exception as e: response_line = "HTTP/1.1 404 Not Found\r\n" response_header = "Server:python-Web 1.1 \r\n" + "\r\n" response_content = "ERROR!!! %s" % e response_content = response_content.encode() else: response_line = "HTTP/1.1 200 OK\r\n" response_header = "Server:python-Web 1.1\r\n" + "\r\n" # # 拼接響應協議 # response_data = (response_line + response_header).encode() + response_content # # 傳送響應協議 # new_socket.send(response_data) # # 關閉套接字 # new_socket.close() else: # 動態資源 env = {'url': path} # 符合wsgi協議的埠 env:字典 傳入回撥函式引用地址,返回狀態嗎碼和響應頭【元組】 response_content = application.app(env, self.start_response) response_line = "HTTP/1.1 %s\r\n" % self.statue response_header = "" # 遍歷元組 for i in self.headers: response_header += "%s:%s\r\n" % (i[0], i[1]) response_header += "\r\n" # 拼接響應協議 response_data = (response_line + response_header).encode() + response_content # 傳送響應資料 new_socket.send(response_data) # 關閉套接字 new_socket.close() # 定義回撥函式 def start_response(self, statue, headers): self.statue = statue self.headers = headers def __del__(self): self.tcp_server_socket.close() if __name__ == '__main__': server = WebServer() server.run()
# 定義路由列表,其實定義的是個字典,也可利用列表套元組的方式,個人偏向字典 route_list = dict() # 設計裝飾器 def route(date): def func1(func): # 新增鍵值對——> 地址:函式 route_list[date] = func def func2(): func() return func2 return func1 @route("/index.py") def index(): try: # 假設呼叫的是index.py檔案 with open("/index.html", 'rb') as file: response_content = file.read() except Exception as e: return ("%s" % e).encode() else: return response_content def app(env, start_response): path = env['url'] statue = "200 OK" headers = [('Connection', 'keep-Alive'), ('Server', 'python-web 1.1')] # 呼叫回撥函式 start_response(statue, headers) try: return route_list[path]() # 自動呼叫路徑對應的函式 except Exception as e: return "%s" % e
附: index.html 內容, 可直接複製建立檔案
<!DOCTYPE html> <html> <head> <title>Welcome </title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to Python Web Server!</h1> <p>If you see this page, the python web server is successfully installed and working.</p> <p><em>Congratulation to you!.</em></p> </body> </html>