异步web框架
import socket import select class HttpRequest(object): """ 用户封装用户请求信息 """ def __init__(self, content): """ :param content: 请求头、请求体 """ self.content = content self.header_bytes = bytes() self.header_dict = {} self.body_bytes = bytes() self.method = "" self.url = "" self.protocol = "" self.initialize() self.initialize_headers() def initialize(self): temp = self.content.split(b'\r\n\r\n', 1) #分割请求体、头 if len(temp) == 1: self.header_bytes += temp else: h, b = temp self.header_bytes += h self.body_bytes += b header_flag = True @property def header_str(self): return str(self.header_bytes, encoding='utf-8') def initialize_headers(self): headers = self.header_str.split('\r\n') first_line = headers[0].split(' ') if len(first_line) == 3: self.method, self.url, self.protocol = headers[0].split(' ') for line in headers: kv = line.split(':') if len(kv) == 2: k, v = kv self.header_dict[k] = v class Future(object): def __init__(self): self.result = None F = None def index(request): global F F = Future() return F def main(request): return 'main' def stop(request): global F F.result = b'sda' return 'stop' routers = [ ('/index/',index), ('/main/',main), ('/stop/',stop), ] def run(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('127.0.0.1', 9999,)) sock.setblocking(False) sock.listen(128) inputs = [] inputs.append(sock) async_request_dict = {} while True: rlist,wlist,elist = select.select(inputs,[],[],0.05) for r in rlist: if r == sock: '''新请求到来''' conn,addr = sock.accept() conn.setblocking(False) #设置客户端socket非阻塞 inputs.append(conn) else: """客户端发来数据""" data = b"" #包含请求头、请求体 while True: try: chunks = r.recv(1024) #接收字节类型 data += chunks except Exception as e: chunks = None if not chunks: break request = HttpRequest(data) # print(request.url) # print(request.method) # print(request.header_dict) # print(request.body_bytes) # 1. 请求头获取url # 2. 路由匹配,获取指定函数 import re flag = False func = None for route in routers: if re.match(route[0],request.url): flag = True func = route[1] break if flag: result = func(request) if isinstance(result,Future): async_request_dict[r]=result #不关闭连接,加入列表 else: r.sendall(bytes(result,encoding='utf-8')) inputs.remove(r) r.close() else: r.sendall(b'404') inputs.remove(r) r.close() # 3. 执行函数,获取返回值 # 4.r.sendall(b'asd') for conn in async_request_dict.keys(): future = async_request_dict[conn] if future.result: conn.sendall(future.result) conn.close() del async_request_dict[conn] inputs.remove(conn) else: pass if __name__ =='__main__': run()