自定义 异步 IO 非阻塞框架
框架一
自定义Web异步非阻塞框架
suosuo.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-#
# __name__ = Web_Framework.server_async.py
# __date__ = 2019/9/3 8:21
# __author__ ='Shi Wei'
# __description__:
# --------------------------------------------------------------
# 服务端
import socket
import select
import re
import time
Buffer_size = 1024
backlog = 5
class HttpRequest:
def __init__(self, conn):
self.socket = conn
self.header_bytes = b''
self.header_dict = {}
self.body_bytes = b''
self.method = ''
self.url = ""
self.protrol = ''
self.initialize()
def header_str(self):
return str(self.header_bytes, encoding="utf-8")
def initialize(self):
self.recv_data = bytes()
while True:
try:
data = self.socket.recv(Buffer_size)
except Exception as e:
data = None
if not data:
break
else:
self.recv_data += data
recv = self.recv_data.split(b'\r\n\r\n', 1)
if len(recv) == 1: # 格式 不正确
self.body_bytes = self.recv_data
else: # 格式正确
self.header_bytes, self.body_bytes = recv
self.initialize_header()
def initialize_header(self):
header_list = self.header_str().split("\r\n")
gen = header_list[0].split(" ")
if len(gen) == 3:
self.method, self.url, self.protrol = gen
for header in header_list:
hea = header.split(":", 1)
if len(hea) == 2:
k, v = hea
self.header_dict[k] = v
class HttpResponse:
def __init__(self, contennt):
self.content = contennt
self.headers = {}
self.cookies = {}
def response(self):
return bytes(self.content, "utf-8")
class HttpNotFound(HttpResponse):
def __init__(self):
super(HttpNotFound, self).__init__("404 Not Found!......")
class Future:
def __init__(self, callback):
self._ready = False
self.callback = callback
self.value = None
def set_result(self, value=None):
self.value = value
self._ready = True
@property
def ready(self):
return self._ready
class TimeoutFuture(Future):
def __init__(self, timeout, callback = None):
super(TimeoutFuture, self).__init__(callback=callback)
self.timeout = timeout
self.start_time = time.time()
@property
def ready(self):
current_time = time.time()
if current_time > self.start_time + self.timeout:
self._ready = True
return self._ready
class Panda:
def __init__(self, routers):
self.routers = routers
self.shiwei = []
self.async_request_handler = {}
self.request = None
def run(self, host="127.0.0.1", port=9999):
sk = socket.socket() #(2, 1)
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #(65535, 4) ###
sk.bind((host, port))
sk.setblocking(False)
sk.listen(backlog)
self.shiwei.append(sk)
try:
while True:
rlist, wlist, elist = select.select(self.shiwei, [], [], 0.05)
for r in rlist:
if r == sk:
conn, addr = sk.accept()
conn.setblocking(False)
self.shiwei.append(conn)
else:
res = self.process(r)
if isinstance(res, HttpResponse):
data = res.response()
r.sendall(data)
self.shiwei.remove(r)
r.close()
else:
self.async_request_handler[r] = res
self.polling_callback() # 处理 异步请求
except Exception as e:
print("server_socket------->Exception msg=", e)
finally:
sk.close()
def polling_callback(self):
del_conn = []
for conn in self.async_request_handler.keys():
future = self.async_request_handler[conn]
if not future.ready:
continue
if future.callback:
res = future.callback(self.request, future)
conn.sendall(res.response())
else:
res = """HTTP/1.1 200 OK\r\nDate: Tue, 03 Sep 2019 01:44:42 GMT\r\n\r\n<html><head><meta charset="UTF-8"></head><body><h1 align="center" style="margin-top: 200px;">shiwei is one Future....<br>callback = None!...</h1></body></html>"""
conn.sendall(bytes(res, encoding="utf-8"))
self.shiwei.remove(conn)
del_conn.append(conn)
conn.close()
for conn in del_conn:
del self.async_request_handler[conn]
del_conn.clear()
def process(self, conn):
""" 处理路由系统 和 执行函数"""
self.request = HttpRequest(conn)
result = HttpNotFound()
for route in self.routers:
if re.match(route[0], self.request.url):
func = route[1]
if func:
response = func(self.request)
result = response
break
return result
使用 suosuo 框架 开发 一个小网站
#!/usr/bin/env python
# -*- coding: utf-8 -*-#
# __name__ = Web_Framework.start01.py
# __date__ = 2019/9/3 9:55
# __author__ ='Shi Wei'
# __description__:
# --------------------------------------------------------------
from server_async import Panda
from server_async import HttpResponse
from server_async import TimeoutFuture
def shi(request):
try:
print("\033[1;31m url=%s--->header_dict=%s\033[0m"%(request.url, request.header_dict))
except Exception as e:
pass
return HttpResponse("the King of Northern!....")
def www(request, future):
return HttpResponse("is future callback func ........")
def wei(request):
try:
print("\033[1;31m url=%s--->header_dict=%s\033[0m"%(request.url, request.header_dict))
except Exception as e:
pass
return TimeoutFuture(5, callback=www)
# return HttpResponse("is wei func ")
routers = [
(r"/shi", shi),
(r'/wei', wei),
]
asy = Panda(routers)
asy.run(port = 9999)
框架二
异步非阻塞 server 端
#!/usr/bin/env python
# -*- coding: utf-8 -*-#
# __name__ = Web_Framework.server_suosuo.py
# __date__ = 2019/8/28 19:10
# __author__ ='Shi Wei'
# __description__:
# --------------------------------------------------------------
""" 异步 非 阻塞 Server 端 """
import socket
import select
import time
Buffer_size = 1024
class HttpRequest:
def __init__(self, conn):
self.conn = conn
self.recv_data = b''
self.header_bytes = bytes()
self.header_dict = {}
self.body_bytes = bytes()
self.method = ""
self.url = ''
self.protocol = ""
self.initialize() # 接受 数据
def initialize(self):
while 1:
try:
data = self.conn.recv(Buffer_size)
except Exception as e:
data = None
if not data:
break
else:
self.recv_data += data
continue
temp = self.recv_data.split(b'\r\n\r\n', 1)
if len(temp) == 1: # 代表 是 坏的 client , 格式不正确
self.body_bytes = self.recv_data
else: # 代表 是 好的 client , 格式 正确
header, body = temp
self.header_bytes += header
self.body_bytes += body
self.initialize_headers() # 切割 请求头 数据
@property
def header_str(self):
return str(self.header_bytes, encoding="utf-8")
def initialize_headers(self):
header_list = self.header_str.split('\r\n')
first_header = header_list[0].split(' ')
if len(first_header) == 3:
self.method, self.url, self.protocol = first_header
for header in header_list:
hea = header.split(':')
if len(hea) == 2:
k, v = hea
self.header_dict[k] = v
def Index(request):
return "is Index Page"
# return "HTTP/1.1 200 OK\r\nDate:Fri, 22 May 2009 06:07:21 GMT\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n"
def Main(request):
return " Main Page Hello ......"
def All(request):
return " HTTP/1.1 200 OK\r\nDate:Fri, 22 May 2009 06:07:21 GMT\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n<html><head</head><body>shiwei</body></html>"
routers = [
("/index$", Index),
('/main$', Main),
('/', All),
]
def run():
ip_port = ("127.0.0.1", 80,)
backlog = 5
shiwei = []
sk = socket.socket(2, 1)
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sk.bind(ip_port)
sk.listen(backlog)
shiwei.append(sk)
while 1:
rlist, wlist, elist = select.select(shiwei, [], [], 0.05)
for r in rlist:
if r == sk:
print('服务端 socket=', r)
conn, addr = sk.accept()
conn.setblocking(False)
shiwei.append(conn)
else:
""" 客户端发来数据 """
print("客户端 socket =",r)
request = HttpRequest(r)
# 1. 请求头中获取url
# 2. 去路由中匹配,获取指定的函数
# 3. 执行函数,获取返回值
# 4. 将返回值 r.sendall(b'alskdjalksdjf;asfd')
import re
flag = False
func = None
print("url=", request.url)
for route in routers:
if re.match(route[0], request.url):
func = route[1]
flag = True
break
if flag:
result = func(request)
r.send(bytes(result, encoding="utf-8"))
shiwei.remove(r)
r.close()
else:
result = "404 Not Page...."
r.send(bytes(result, encoding="utf-8"))
shiwei.remove(r)
r.close()
print("url=%s,--->result=%s" % (request.url, result))
if __name__ == '__main__':
run()
异步 非 阻塞 Client 端
#!/usr/bin/env python
# -*- coding: utf-8 -*-#
# __name__ = Web_Framework.client_suosuo.py
# __date__ = 2019/8/29 8:34
# __author__ ='Shi Wei'
# __description__:
# --------------------------------------------------------------
""" 异步 非 阻塞 Client 端 """
import socket
import select
Buffer_size = 1024
class HttpRequest:
def __init__(self, sk, url, host, callback):
self.socket = sk
self.url = url
self.host = host
self.callback = callback
def fileno(self):
return self.socket.fileno()
class HttpResponse:
def __init__(self,recv_data):
self.recv_data = recv_data
self.http_version = ""
self.status_code = ''
self.status_msg = ""
self.header_bytes = b''
self.header_dict = {}
self.body_bytes = b''
self.initialize()
@property
def header_str(self):
return self.header_bytes.decode("utf-8")
def initialize(self):
data = self.recv_data.split(b'\r\n\r\n', 1)
if len(data) == 1: # 没有分割 , 服务端不按照正常格式发送数据
self.body_bytes = data[0]
else: # 代表分割了, 可能为 ["xxxxxxxx", ''], 按照正常格式
h, b = data
self.header_bytes = h
self.body_bytes = b
self.initialize_header()
def initialize_header(self):
header_list = self.header_str.split("\r\n")
temp = header_list[0].split(" ")
if len(temp) == 3:
ht = temp[0].split('/')
if len(ht) == 2:
self.http_version = ht[1]
self.status_code, self.status_msg = temp[1], temp[2]
for header in header_list:
var = header.split(':')
if len(var) == 2:
k, v = var
self.header_dict[k] = v
class AsyncRequest:
def __init__(self):
self.shiwei = []
self.haiyan = []
def add_request(self,url, host, callback):
try:
sk = socket.socket()
sk.setblocking(False)
sk.connect((host, 80))
except Exception as e:
pass
request = HttpRequest(sk, url, host, callback)
self.shiwei.append(request)
self.haiyan.append(request)
def run(self):
while 1:
rlist, wlist, elist = select.select(self.shiwei, self.haiyan, self.shiwei, 0.05)
for w in wlist:
sendstr = "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n"%(w.url, w.host)
data = sendstr.encode("utf-8")
w.socket.send(data)
self.haiyan.remove(w)
for r in rlist:
recv_data = bytes()
while 1:
try:
data = r.socket.recv(Buffer_size)
except Exception as e:
data = None
if not data:
break
else:
recv_data += data
# print("%s--->%s"%(r.host, str(recv_data, encoding="utf-8")))
response = HttpResponse(recv_data)
r.callback(response)
self.shiwei.remove(r)
if not self.shiwei:
break
def f1(response):
print("\033[1;30m 保存到文件中, 接收到的数据为: %s \033[0m"%(str(response.body_bytes, encoding="utf-8")))
def f2(response):
print("\033[1;43m 保存到数据库中,接收到的数据为: %s \033[0m"%(str(response.body_bytes, encoding="utf-8")))
urls = [
# {"url": "/", "host": 'www.baidu.com', "callback": f1},
# {"url": "/", "host": 'www.autohome.com', "callback": f2},
{"url": "/index", "host": '127.0.0.1', "callback": f2},
{"url": "/main", "host": "127.0.0.1", "callback": f1},
]
asy = AsyncRequest()
if __name__ == '__main__':
for tem in urls:
asy.add_request(**tem)
print(asy.shiwei)
asy.run()
Wupeiqi--Web Framework
自定义 异步 IO 非阻塞框架的更多相关文章
- 爬虫之多线程 多进程 自定义异步IO框架
什么是进程? 进程是程序运行的实例,是系统进行资源分配和调度的一个独立单位,它包括独立的地址空间,资源以及1个或多个线程. 什么是线程? 线程可以看成是轻量级的进程,是CPU调度和分派的基本单位. 进 ...
- IO模型--阻塞IO,非阻塞IO,IO多路复用,异步IO
IO模型介绍: * blocking IO 阻塞IO * nonblocking IO 非阻塞IO * IO multiplexing IO多路复用 * signal driven IO 信号驱动IO ...
- python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)
昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...
- {python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块
python之IO多路复用 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 ...
- (IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)
参考博客: https://www.cnblogs.com/xiao987334176/p/9056511.html 内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yi ...
- 简述同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别
POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...
- 同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别
POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...
- IO复用\阻塞IO\非阻塞IO\同步IO\异步IO
转载:IO复用\阻塞IO\非阻塞IO\同步IO\异步IO 一. 什么是IO复用? 它是内核提供的一种同时监控多个文件描述符状态改变的一种能力:例如当进程需要操作多个IO相关描述符时(例如服务器程序要同 ...
- 通俗讲解 异步,非阻塞和 IO 复用
1. 阅前热身 为了更加形象的说明同步异步.阻塞非阻塞,我们以小明去买奶茶为例. 1.1 同步与异步 同步与异步的理解 同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式. 同步: 当一个同 ...
随机推荐
- LeetCode--040--组合总和 II(java)
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用一次. ...
- 17 安全字符串 System.Security.SecureString
- UI自动化前置代码
一.前置代码: #导入包selenium from selenium import webdriverimport time#创键一个火狐对象driver=webdriver.Firefox()#防问 ...
- [USACO17FEB]Why Did the Cow Cross the Road III G (树状数组,排序)
题目链接 Solution 二维偏序问题. 现将所有点按照左端点排序,如此以来从左至右便满足了 \(a_i<a_j\) . 接下来对于任意一个点 \(j\) ,其之前的所有节点都满足 \(a_i ...
- 2、投资之基金 - IT人思维之投资
笔者曾经对基金进行投资,但是当时对基金不是很了解,只是为了投资而去投资.现在,笔者对基金的投资有了更深入的了解认识,所以就有了本文. 基金投资在国内还是挺流行的,虽然其是从国外引进来的概念经验,但是国 ...
- 2017年度最具商业价值人工智能公司TOP50 榜单发布
2017年度最具商业价值人工智能公司TOP50 榜单发布 未来最有赚钱潜力的50个人工智能项目都在这里了. 经过了60年的发展,人工智能在2017年,正式走向应用的元年. 从今年起,人工智能首次被写入 ...
- react-navigation 实战
npm install --save react-navigation 1.测试TabNavigator.StackNavigator和DrawerNavigator (1)新建HomeScreen. ...
- TimeInOfficePresent
w x <- c(52, 30, 10, 8)labels <- c("分析思考", "写代码.调试", "沟通", " ...
- 【CDN+】 Hbase入门 以及Hbase shell基础命令
前言 大数据的基础离不开Hbase, 本文就hbase的基础概念,特点,以及框架进行简介, 实际操作种需要注意hbase shell的使用. Hbase 基础 官网:https://hbase.ap ...
- tomcat 迁移到weblogic 问题
问题1: Caused by: java.lang.UnsupportedClassVersionError: com/audaque/datadiscovery/soap/service/impl/ ...