1.自定义异步IO模块

HTTP请求本质,阻塞
 1 sk = socket.socket()
 2 # 1.连接
 3 sk.connect(('www.baidu.com',80,)) # IO阻塞
 4 print('连接成功了...')
 5 
 6 # 2. 连接成功发送消息
 7 sk.send(b'GET / HTTP/1.0\r\nHost:www.baidu.com\r\n\r\n')
 8 # sk.send(b'POST / HTTP/1.0\r\nHost:www.baidu.com\r\n\r\nk1=v1&k2=v2')
 9 
10 # 3. 等待着服务端响应
11 data = sk.recv(8096) # IO阻塞
12 print(data)
13 
14 # 关闭连接
15 sk.close()
HTTP请求本质,阻塞
 
 1、自定义异步IO模块(客户端)
  IO多路复用:r,w,e = while 监听多个socket对象
    r:表示有人给我发送数据
    w:表示已经与别人创建连接成功
    e:错误相关
 
  异步IO模块(客户端):非阻塞的socket(sk.setblocking(0)),与IO多路复用结合,实现:
    作为客户端向服务端发起“并发”请求,select监听socket是否已经有变化
 
 1 import socket
 2 import select
 3 
 4 
 5 class HttpRequest:
 6     def __init__(self,sk,host,callback):
 7         self.socket = sk
 8         self.host = host
 9         self.callback = callback
10     def fileno(self):
11         return self.socket.fileno()
12 
13 class HttpResponse:
14     def __init__(self,recv_data):
15         self.recv_data = recv_data
16         self.header_dict = {}
17         self.body = None
18 
19         self.initialize()
20     def initialize(self):
21         headers, body = self.recv_data.split(b'\r\n\r\n', 1)
22         self.body = body
23         header_list = headers.split(b'\r\n')
24         for h in header_list:
25             h_str = str(h,encoding='utf-8')
26             v = h_str.split(':',1)
27             # print ("v:",v)
28             if len(v) == 2:
29                 self.header_dict[v[0]] = v[1]
30 
31 
32 class AsyncRequest:
33     def __init__(self):
34         self.conn = []
35         self.connection = [] # 用于检测是否已经连接成功
36 
37     def add_request(self,host,callback):
38         try:
39             sk = socket.socket()
40             sk.setblocking(0)
41             sk.connect((host,80,))
42         except BlockingIOError as e:
43             pass
44         request = HttpRequest(sk,host,callback)
45         self.conn.append(request)
46         self.connection.append(request)
47 
48     def run(self):
49 
50         while True:
51             rlist,wlist,elist = select.select(self.conn,self.connection,self.conn,0.05)
52             for w in wlist:
53                 print(w.host,'连接成功...')
54                 # 只要能循环到,表示socket和服务器端已经连接成功
55                 tpl = "GET / HTTP/1.0\r\nHost:%s\r\n\r\n"  %(w.host,)
56                 w.socket.send(bytes(tpl,encoding='utf-8'))
57                 self.connection.remove(w)
58             for r in rlist:
59                 # r,是HttpRequest
60                 recv_data = bytes()#字节类型
61                 while True:
62                     try:
63                         chunck = r.socket.recv(8096)
64                         recv_data += chunck
65                     except Exception as e:
66                         break
67                 response = HttpResponse(recv_data)
68                 r.callback(response)
69                 r.socket.close()
70                 self.conn.remove(r)
71             if len(self.conn) == 0:
72                 break
73 
74 def f1(response):
75     print('保存到文件',response.header_dict)
76 
77 def f2(response):
78     print('保存到数据库', response.header_dict)
79 
80 url_list = [
81     {'host':'www.baidu.com','callback': f1},
82     {'host':'cn.bing.com','callback': f2},
83     {'host':'www.cnblogs.com','callback': f2},
84 ]
85 
86 req = AsyncRequest()
87 for item in url_list:
88     req.add_request(item['host'],item['callback'])
89 
90 req.run()
自定义异步IO模块

 

    2.1、自定义同步非阻塞web服务端

  1 import socket
  2 import select
  3 import time
  4 from login_test import settings
  5 import os
  6 
  7 class HttpRequest(object):
  8     """
  9     用户封装用户请求信息
 10     """
 11     def __init__(self, content):
 12         """
 13 
 14         :param content:用户发送的请求数据:请求头和请求体
 15         """
 16         print("content:",content)
 17         self.content = content
 18 
 19         self.header_bytes = bytes()
 20         self.body_bytes = bytes()
 21 
 22         self.header_dict = {}
 23 
 24         self.method = ""
 25         self.url = ""
 26         self.protocol = ""
 27 
 28         self.initialize()
 29         self.initialize_headers()
 30 
 31     def initialize(self):
 32 
 33         temp = self.content.split(b'\r\n\r\n', 1)
 34         print("temp:",temp)
 35         if len(temp) == 1:# 只有请求头
 36             self.header_bytes += temp
 37         else:
 38             h, b = temp # h:请求头,b:请求体
 39             self.header_bytes += h
 40             self.body_bytes += b
 41 
 42     @property
 43     def header_str(self):# 将字节转化成字符串,方便分割
 44 
 45         return str(self.header_bytes, encoding='utf-8')
 46 
 47     def initialize_headers(self):
 48 
 49         headers = self.header_str.split('\r\n')
 50         first_line = headers[0].split(' ') # first_line: ['GET', '/', 'HTTP/1.1'] or ['GET', '/favicon.ico', 'HTTP/1.1']
 51         # print("first_line:",first_line)
 52         if len(first_line) == 3:
 53             self.method, self.url, self.protocol = headers[0].split(' ')
 54             for line in headers:
 55                 kv = line.split(':')
 56                 if len(kv) == 2:
 57                     k, v = kv
 58                     self.header_dict[k] = v
 59 
 60 # 响应头 响应头 ,回复时用
 61 index_content = '''
 62 HTTP/1.1 200 OK
 63 Content-Type: text/html
 64 \r\n\r\n
 65 '''
 66 
 67 
 68 
 69 test_login_dir = os.path.join(settings.TEMPLATES[0]["DIRS"][0],"test_login.html")
 70 # print(test_login_dir) # G:\Python\login_test\templates\test_login.html
 71 file = open(test_login_dir, 'r',encoding='utf-8')
 72 index_content += file.read()
 73 file.close()
 74 
 75 
 76 def run():
 77     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 78     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 79     sock.bind(("127.0.0.1", 9999,))
 80     sock.setblocking(False)
 81     sock.listen(128)
 82 
 83     inputs = []
 84     inputs.append(sock)
 85 
 86     async_request_dict = {
 87         # 'socket': futrue
 88     }
 89 
 90     while True:
 91         rlist,wlist,elist = select.select(inputs,[],[],0.05)
 92         for r in rlist:
 93             if r == sock:
 94                 print("123")
 95                 """新请求到来"""
 96                 conn,addr = sock.accept()
 97                 conn.setblocking(False)
 98                 inputs.append(conn)
 99             else:
100                 """客户端发来数据"""
101                 print("456")
102 
103                 data = b""
104                 while True:
105                     try:
106                         chunk = r.recv(1024)
107                         data = data + chunk
108                     except Exception as e:
109                         chunk = None
110                     if not chunk:
111                         break
112 
113                 result = HttpRequest(data)
114 
115                 r.sendall(bytes(index_content ,encoding='utf-8'))
116                 # r.sendall(b'HTTP/1.1 200 OK\r\n\r\n<html><body>hello</body></html>')
117 
118                 inputs.remove(r)
119                 r.close()
120 
121 
122 
123 if __name__ == '__main__':
124     run()
自定义同步非阻塞web服务端

 

 2.2、自定义异步非阻塞web框架(服务端)

  注:当在非Future对象中使用time.sleep等,无法实现并发操作,线程会被hang住

  1 import socket
  2 import select
  3 import time
  4 
  5 """
  6 异步非阻塞框架(服务端):
  7   设置 future = Future(),通过Future实现异步非阻塞
  8       1. 当设置 future = Future()时,挂起当前请求,线程可以处理其他请求 
  9       2. 当给future设置值时,当前挂起的请求返回
 10 """
 11 
 12 class HttpRequest(object):
 13     """
 14     用户封装用户请求信息
 15     """
 16     def __init__(self, content):
 17         """
 18 
 19         :param content:用户发送的请求数据:请求头和请求体
 20         """
 21         self.content = content
 22 
 23         self.header_bytes = bytes()
 24         self.body_bytes = bytes()
 25 
 26         self.header_dict = {}
 27 
 28         self.method = ""
 29         self.url = ""
 30         self.protocol = ""
 31 
 32         self.initialize()
 33         self.initialize_headers()
 34 
 35     def initialize(self):
 36 
 37         temp = self.content.split(b'\r\n\r\n', 1)
 38         if len(temp) == 1:
 39             self.header_bytes += temp[0]
 40         else:
 41             h, b = temp
 42             self.header_bytes += h
 43             self.body_bytes += b
 44 
 45     @property
 46     def header_str(self):
 47         return str(self.header_bytes, encoding='utf-8')
 48 
 49     def initialize_headers(self):
 50         headers = self.header_str.split('\r\n')
 51         first_line = headers[0].split(' ')
 52         if len(first_line) == 3:
 53             self.method, self.url, self.protocol = headers[0].split(' ')
 54             for line in headers:
 55                 kv = line.split(':')
 56                 if len(kv) == 2:
 57                     k, v = kv
 58                     self.header_dict[k] = v
 59 
 60 class Future(object):
 61     def __init__(self):
 62         self.result = None
 63 F = Future()
 64 def main(request):
 65     global F
 66     return F # Future对象
 67 
 68 def stop(request):
 69     global F
 70     F.result = b"xxxxxxxxxxxxx"
 71     return "stop"
 72 
 73 
 74 def index(request):
 75 
 76     return "indexasdfasdfasdf"
 77 
 78 
 79 routers = [
 80     ('/main/',main),
 81     ('/index/',index),
 82     ('/stop/',stop),
 83 ]
 84 
 85 def run():
 86     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 87     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 88     sock.bind(("127.0.0.1", 9999,))
 89     sock.setblocking(False)
 90     sock.listen(128)
 91 
 92     inputs = []
 93     inputs.append(sock)
 94 
 95     async_request_dict = {
 96         # 'socket': futrue
 97     }
 98 
 99     while True:
100         rlist,wlist,elist = select.select(inputs,[],[],0.05)
101         for r in rlist:
102             if r == sock:
103                 """新请求到来"""
104                 conn,addr = sock.accept()
105                 conn.setblocking(False)
106                 inputs.append(conn)
107             else:
108                 """客户端发来数据"""
109                 data = b""
110                 while True:
111                     try:
112                         chunk = r.recv(1024)
113                         data = data + chunk
114                     except Exception as e:
115                         chunk = None
116                     if not chunk:
117                         break
118                 # data进行处理:请求头和请求体
119                 request = HttpRequest(data)
120                 # 1. 请求头中获取url
121                 # 2. 去路由中匹配,获取指定的函数
122                 # 3. 执行函数,获取返回值
123                 # 4. 将返回值 r.sendall(b'alskdjalksdjf;asfd')
124                 import re
125                 flag = False
126                 func = None
127                 for route in routers:
128                     if re.match(route[0],request.url):
129                         print(route[0],request.url)
130                         flag = True
131                         func = route[1]
132                         break
133                 if flag: # url路径匹配成功
134                     result = func(request) # 执行函数
135                     if isinstance(result,Future):# 判断是否Future对象,如是则挂起不执行,否则执行服务端响应操作
136                         async_request_dict[r] = result
137                     else:
138                         r.sendall(b'HTTP/1.1 200 OK\r\n\r\n<html><body>hello</body></html>')
139                         inputs.remove(r)
140                         r.close()
141                 else:# 匹配不成功,返回404错误
142                     r.sendall(b"HTTP/1.1 200 OK\r\n\r\n<html><body>404</body></html>")
143                     inputs.remove(r)
144                     r.close()
145 
146 
147         for conn in list(async_request_dict.keys()):# 当Future函数中result有值,才执行。实现可控制的异步非阻塞操作
148             future = async_request_dict[conn]
149             if future.result:
150                 conn.sendall(b'HTTP/1.1 200 OK\r\n\r\n<html><body>hello</body></html>')
151                 conn.close()
152                 del async_request_dict[conn]
153                 inputs.remove(conn)
154 
155 if __name__ == '__main__':
156     run()
自定义异步非阻塞web框架

 

主要:

 2.3、自定义异步非阻塞web框架(服务端)

  通过Future设置,实现并发操作

 

  1 import socket
  2 import select
  3 import time
  4 
  5 class HttpRequest(object):
  6     """
  7     用户封装用户请求信息
  8     """
  9     def __init__(self, content):
 10         """
 11 
 12         :param content:用户发送的请求数据:请求头和请求体
 13         """
 14         self.content = content
 15 
 16         self.header_bytes = bytes()
 17         self.body_bytes = bytes()
 18 
 19         self.header_dict = {}
 20 
 21         self.method = ""
 22         self.url = ""
 23         self.protocol = ""
 24 
 25         self.initialize()
 26         self.initialize_headers()
 27 
 28     def initialize(self):
 29 
 30         temp = self.content.split(b'\r\n\r\n', 1)
 31         if len(temp) == 1:
 32             self.header_bytes += temp[0]
 33         else:
 34             h, b = temp
 35             self.header_bytes += h
 36             self.body_bytes += b
 37 
 38     @property
 39     def header_str(self):
 40         return str(self.header_bytes, encoding='utf-8')
 41 
 42     def initialize_headers(self):
 43         headers = self.header_str.split('\r\n')
 44         first_line = headers[0].split(' ')
 45         if len(first_line) == 3:
 46             self.method, self.url, self.protocol = headers[0].split(' ')
 47             for line in headers:
 48                 kv = line.split(':')
 49                 if len(kv) == 2:
 50                     k, v = kv
 51                     self.header_dict[k] = v
 52 
 53 class Future(object):
 54     def __init__(self,timeout=0):
 55         self.result = None
 56         self.timeout = timeout
 57         self.start = time.time()
 58 def main(request):
 59     #挂起当前请求,5秒后返回当前挂起请求
 60     f = Future(5)
 61     return f
 62 
 63 def index(request):
 64     return "indexasdfasdfasdf"
 65 
 66 
 67 routers = [
 68     ('/main/',main),
 69     ('/index/',index),
 70 ]
 71 
 72 def run():
 73     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 74     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 75     sock.bind(("127.0.0.1", 9999,))
 76     sock.setblocking(False)
 77     sock.listen(128)
 78 
 79     inputs = []
 80     inputs.append(sock)
 81 
 82     async_request_dict = {
 83         # 'socket': futrue
 84     }
 85 
 86     while True:
 87         rlist,wlist,elist = select.select(inputs,[],[],0.05)
 88         for r in rlist:
 89             if r == sock:
 90                 """新请求到来"""
 91                 conn,addr = sock.accept()
 92                 conn.setblocking(False)
 93                 inputs.append(conn)
 94             else:
 95                 """客户端发来数据"""
 96                 data = b""
 97                 while True:
 98                     try:
 99                         chunk = r.recv(1024)
100                         data = data + chunk
101                     except Exception as e:
102                         chunk = None
103                     if not chunk:
104                         break
105                 # data进行处理:请求头和请求体
106                 request = HttpRequest(data)
107                 # 1. 请求头中获取url
108                 # 2. 去路由中匹配,获取指定的函数
109                 # 3. 执行函数,获取返回值
110                 # 4. 将返回值 r.sendall(b'alskdjalksdjf;asfd')
111                 import re
112                 flag = False
113                 func = None
114                 for route in routers:
115                     if re.match(route[0],request.url):
116                         flag = True
117                         func = route[1]
118                         break
119                 if flag:
120                     result = func(request)
121                     if isinstance(result,Future):
122                         async_request_dict[r] = result
123                     else:
124                         r.sendall(b'HTTP/1.1 200 OK\r\n\r\n<html><body>hello,baby!</body></html>')
125                         inputs.remove(r)
126                         r.close()
127                 else:
128                     r.sendall(b"HTTP/1.1 200 OK\r\n\r\n<html><body>404</body></html>")
129                     inputs.remove(r)
130                     r.close()
131 
132         for conn in list(async_request_dict.keys()):
133             future = async_request_dict[conn]
134             start = future.start
135             timeout = future.timeout
136             ctime = time.time()
137             if (start + timeout) <= ctime :
138                 future.result = b"timeout"
139             if future.result:
140                 conn.sendall(b'HTTP/1.1 200 OK\r\n\r\n<html><body>hello web</body></html>')
141                 conn.close()
142                 del async_request_dict[conn]
143                 inputs.remove(conn)
144 
145 if __name__ == '__main__':
146     run()
自定义异步非阻塞web框架

 

 

 转载:

 自定义异步非阻塞Web框架(服务器)
  1 #!/usr/bin/env python
  2 # -*- coding:utf-8 -*-
  3 import re
  4 import socket
  5 import select
  6 import time
  7 
  8 
  9 class HttpResponse(object):
 10     """
 11     封装响应信息
 12     """
 13     def __init__(self, content=''):
 14         self.content = content
 15 
 16         self.headers = {}
 17         self.cookies = {}
 18 
 19     def response(self):
 20         return bytes(self.content, encoding='utf-8')
 21 
 22 
 23 class HttpNotFound(HttpResponse):
 24     """
 25     404时的错误提示
 26     """
 27     def __init__(self):
 28         super(HttpNotFound, self).__init__('404 Not Found')
 29 
 30 
 31 class HttpRequest(object):
 32     """
 33     用户封装用户请求信息
 34     """
 35     def __init__(self, conn):
 36         self.conn = conn
 37 
 38         self.header_bytes = bytes()
 39         self.header_dict = {}
 40         self.body_bytes = bytes()
 41 
 42         self.method = ""
 43         self.url = ""
 44         self.protocol = ""
 45 
 46         self.initialize()
 47         self.initialize_headers()
 48 
 49     def initialize(self):
 50 
 51         header_flag = False
 52         while True:
 53             try:
 54                 received = self.conn.recv(8096)
 55             except Exception as e:
 56                 received = None
 57             if not received:
 58                 break
 59             if header_flag:
 60                 self.body_bytes += received
 61                 continue
 62             temp = received.split(b'\r\n\r\n', 1)
 63             if len(temp) == 1:
 64                 self.header_bytes += temp
 65             else:
 66                 h, b = temp
 67                 self.header_bytes += h
 68                 self.body_bytes += b
 69                 header_flag = True
 70 
 71     @property
 72     def header_str(self):
 73         return str(self.header_bytes, encoding='utf-8')
 74 
 75     def initialize_headers(self):
 76         headers = self.header_str.split('\r\n')
 77         first_line = headers[0].split(' ')
 78         if len(first_line) == 3:
 79             self.method, self.url, self.protocol = headers[0].split(' ')
 80             for line in headers:
 81                 kv = line.split(':')
 82                 if len(kv) == 2:
 83                     k, v = kv
 84                     self.header_dict[k] = v
 85 
 86 
 87 class Future(object):
 88     """
 89     异步非阻塞模式时封装回调函数以及是否准备就绪
 90     """
 91     def __init__(self, callback):
 92         self.callback = callback
 93         self._ready = False
 94         self.value = None
 95 
 96     def set_result(self, value=None):
 97         self.value = value
 98         self._ready = True
 99 
100     @property
101     def ready(self):
102         return self._ready
103 
104 
105 class TimeoutFuture(Future):
106     """
107     异步非阻塞超时
108     """
109     def __init__(self, timeout):
110         super(TimeoutFuture, self).__init__(callback=None)
111         self.timeout = timeout
112         self.start_time = time.time()
113 
114     @property
115     def ready(self):
116         current_time = time.time()
117         if current_time > self.start_time + self.timeout:
118             self._ready = True
119         return self._ready
120 
121 
122 class Snow(object):
123     """
124     微型Web框架类
125     """
126     def __init__(self, routes):
127         self.routes = routes
128         self.inputs = set()
129         self.request = None
130         self.async_request_handler = {}
131 
132     def run(self, host='localhost', port=9999):
133         """
134         事件循环
135         :param host:
136         :param port:
137         :return:
138         """
139         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
140         sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
141         sock.bind((host, port,))
142         sock.setblocking(False)
143         sock.listen(128)
144         sock.setblocking(0)
145         self.inputs.add(sock)
146         try:
147             while True:
148                 readable_list, writeable_list, error_list = select.select(self.inputs, [], self.inputs,0.005)
149                 for conn in readable_list:
150                     if sock == conn:
151                         client, address = conn.accept()
152                         client.setblocking(False)
153                         self.inputs.add(client)
154                     else:
155                         gen = self.process(conn)
156                         if isinstance(gen, HttpResponse):
157                             conn.sendall(gen.response())
158                             self.inputs.remove(conn)
159                             conn.close()
160                         else:
161                             yielded = next(gen)
162                             self.async_request_handler[conn] = yielded
163                 self.polling_callback()
164 
165         except Exception as e:
166             pass
167         finally:
168             sock.close()
169 
170     def polling_callback(self):
171         """
172         遍历触发异步非阻塞的回调函数
173         :return:
174         """
175         for conn in list(self.async_request_handler.keys()):
176             yielded = self.async_request_handler[conn]
177             if not yielded.ready:
178                 continue
179             if yielded.callback:
180                 ret = yielded.callback(self.request, yielded)
181                 conn.sendall(ret.response())
182             self.inputs.remove(conn)
183             del self.async_request_handler[conn]
184             conn.close()
185 
186     def process(self, conn):
187         """
188         处理路由系统以及执行函数
189         :param conn:
190         :return:
191         """
192         self.request = HttpRequest(conn)
193         func = None
194         for route in self.routes:
195             if re.match(route[0], self.request.url):
196                 func = route[1]
197                 break
198         if not func:
199             return HttpNotFound()
200         else:
201             return func(self.request)
200行实现异步非阻塞框架

 

 测试demo:

  1 import socket
  2 import select
  3 import time
  4 
  5 class HttpRequest(object):
  6     """
  7     用户封装用户请求信息
  8     """
  9     def __init__(self, content):
 10         """
 11 
 12         :param content:用户发送的请求数据:请求头和请求体
 13         """
 14         self.content = content
 15 
 16         self.header_bytes = bytes()
 17         self.body_bytes = bytes()
 18 
 19         self.header_dict = {}
 20 
 21         self.method = ""
 22         self.url = ""
 23         self.protocol = ""
 24 
 25         self.initialize()
 26         self.initialize_headers()
 27 
 28     def initialize(self):
 29 
 30         temp = self.content.split(b'\r\n\r\n', 1)
 31         if len(temp) == 1:
 32             self.header_bytes += temp
 33         else:
 34             h, b = temp
 35             self.header_bytes += h
 36             self.body_bytes += b
 37 
 38     @property
 39     def header_str(self):
 40         return str(self.header_bytes, encoding='utf-8')
 41 
 42     def initialize_headers(self):
 43         headers = self.header_str.split('\r\n')
 44         first_line = headers[0].split(' ')
 45         if len(first_line) == 3:
 46             self.method, self.url, self.protocol = headers[0].split(' ')
 47             for line in headers:
 48                 kv = line.split(':')
 49                 if len(kv) == 2:
 50                     k, v = kv
 51                     self.header_dict[k] = v
 52 
 53 class Future(object):
 54     def __init__(self,timeout=0):
 55         self.result = None
 56         self.timeout = timeout
 57         self.start = time.time()
 58 def main(request):
 59     f = Future(5)
 60     return f
 61 
 62 def index(request):
 63     return "indexasdfasdfasdf"
 64 
 65 
 66 routers = [
 67     ('/main/',main),
 68     ('/index/',index),
 69 ]
 70 
 71 def run():
 72     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 73     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 74     sock.bind(("127.0.0.1", 9999,))
 75     sock.setblocking(False)
 76     sock.listen(128)
 77 
 78     inputs = []
 79     inputs.append(sock)
 80 
 81     async_request_dict = {
 82         # 'socket': futrue
 83     }
 84 
 85     while True:
 86         rlist,wlist,elist = select.select(inputs,[],[],0.05)
 87         for r in rlist:
 88             if r == sock:
 89                 """新请求到来"""
 90                 conn,addr = sock.accept()
 91                 conn.setblocking(False)
 92                 inputs.append(conn)
 93             else:
 94                 """客户端发来数据"""
 95                 data = b""
 96                 while True:
 97                     try:
 98                         chunk = r.recv(1024)
 99                         data = data + chunk
100                     except Exception as e:
101                         chunk = None
102                     if not chunk:
103                         break
104                 # data进行处理:请求头和请求体
105                 request = HttpRequest(data)
106                 # 1. 请求头中获取url
107                 # 2. 去路由中匹配,获取指定的函数
108                 # 3. 执行函数,获取返回值
109                 # 4. 将返回值 r.sendall(b'alskdjalksdjf;asfd')
110                 import re
111                 flag = False
112                 func = None
113                 for route in routers:
114                     if re.match(route[0],request.url):
115                         flag = True
116                         func = route[1]
117                         break
118                 if flag:
119                     result = func(request)
120                     if isinstance(result,Future):
121                         async_request_dict[r] = result
122                     else:
123                         r.sendall(bytes(result,encoding='utf-8'))
124                         inputs.remove(r)
125                         r.close()
126                 else:
127                     r.sendall(b"404")
128                     inputs.remove(r)
129                     r.close()
130 
131         for conn in async_request_dict.keys():
132             future = async_request_dict[conn]
133             start = future.start
134             timeout = future.timeout
135             ctime = time.time()
136             if (start + timeout) <= ctime :
137                 future.result = b"timeout"
138             if future.result:
139                 conn.sendall(future.result)
140                 conn.close()
141                 del async_request_dict[conn]
142                 inputs.remove(conn)
143 
144 if __name__ == '__main__':
145     run()
测试demo

 

posted on 2018-07-25 17:39  Eric_nan  阅读(135)  评论(0)    收藏  举报