- #!/usr/bin/env python
- # -*- coding:utf8 -*-
- from socket import *
- import select
- from threading import Thread
- class Future:
- def __init__(self,callback):
- self.__result = ''
- self.state = False
- self.callback = callback
- def set_result(self,result):
- self.__result = result
- @property
- def result(self):
- return self.__result
- def finish(self):
- # 回调函数的最后需要执行它, 用来判断是否需要返回值
- self.state = True
- class HTTPRequset(object):
- def __init__(self, request):
- self.request_body = ''self.request_header =''
- self.request = request.decode()
- self.method = ''self.url =''
- self.protocol = ''
- self.header_dict = {}
- self.initialization()
- self.initialization_header()
- def initialization(self):
- content_list = self.request.split('\r\n\r\n', 1)
- if len(content_list) == 2:
- self.request_header, self.request_body = content_list
- else:
- self.request_header = content_list[0]
- def initialization_header(self):
- line = self.request_header.split('\r\n')
- if len(line[0].split(' ', 2)) == 3:
- self.method, self.url, self.protocol = line[0].split(' ', 2)
- for i in line[1:]:
- try:
- fields, value = i.split(':', 1)
- self.header_dict[fields] = value.strip()
- except Exception:
- pass
- class Easyweb():
- def __init__(self, port):
- self.port = port
- self.request = ''
- self.url_rule = {}
- self.asyn = {}
- # @root.route('/index/')
- # 用装饰器进行路由配置
- def route(self, url):
- def deco(func):
- self.url_rule[url] = func
- return func
- return deco
- def run(self):
- self.sever = socket()
- self.sever.bind(('127.0.0.1', self.port))
- self.sever.listen(5)
- self.sever.setblocking(False)
- self.inputs = []
- self.inputs.append(self.sever)
- try:
- while True:
- rlist, wlist, elist = select.select(self.inputs, [], [], 0.5)
- for items in rlist:
- if items == self.sever:
- conn, addr = items.accept()
- conn.setblocking(False)
- self.inputs.append(conn)
- else:
- info = b''
- while True:
- try:
- chunk = items.recv(1024)
- info += chunk
- except Exception:
- break
- request = HTTPRequset(info)
- url = request.url
- func = self.url_rule.get(url)
- if not func:
- items.sendall(b'404')
- self.close(items)
- else:
- response = func(request)
- # 不是字符串时执行
- if not isinstance(response,str):
- # 新线程处理
- # 返回 Future 对象
- response = next(response)
- # 将 request 传给回调函数
- t=Thread(target=response.callback,args=(response,request))
- t.start()
- # 加入轮询字典中
- self.asyn[items] = response
- else:
- items.sendall(response.encode('utf8'))
- self.close(items)
- self.asyn_state()
- except Exception:
- pass
- def asyn_state(self):
- if not self.asyn:
- return
- for conn,future in self.asyn.items():
- if future.state == False:
- pass
- else:
- conn.sendall(future.result.encode('utf8'))
- self.close(conn)
- self.asyn.pop(conn)
- return
- def close(self,items):
- items.close()
- self.inputs.remove(items)
- def render(templates):
- with open(templates, 'r', encoding='utf8') as f:
- return f.read()
来源: https://www.cnblogs.com/ifyoushuai/p/9501434.html