框架一

自定义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 非阻塞框架的更多相关文章

  1. 爬虫之多线程 多进程 自定义异步IO框架

    什么是进程? 进程是程序运行的实例,是系统进行资源分配和调度的一个独立单位,它包括独立的地址空间,资源以及1个或多个线程. 什么是线程? 线程可以看成是轻量级的进程,是CPU调度和分派的基本单位. 进 ...

  2. IO模型--阻塞IO,非阻塞IO,IO多路复用,异步IO

    IO模型介绍: * blocking IO 阻塞IO * nonblocking IO 非阻塞IO * IO multiplexing IO多路复用 * signal driven IO 信号驱动IO ...

  3. python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

  4. {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) 五 ...

  5. (IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    参考博客: https://www.cnblogs.com/xiao987334176/p/9056511.html 内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yi ...

  6. 简述同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别

    POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...

  7. 同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别

    POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...

  8. IO复用\阻塞IO\非阻塞IO\同步IO\异步IO

    转载:IO复用\阻塞IO\非阻塞IO\同步IO\异步IO 一. 什么是IO复用? 它是内核提供的一种同时监控多个文件描述符状态改变的一种能力:例如当进程需要操作多个IO相关描述符时(例如服务器程序要同 ...

  9. 通俗讲解 异步,非阻塞和 IO 复用

    1. 阅前热身 为了更加形象的说明同步异步.阻塞非阻塞,我们以小明去买奶茶为例. 1.1 同步与异步 同步与异步的理解 同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式. 同步: 当一个同 ...

随机推荐

  1. LeetCode--040--组合总和 II(java)

    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的每个数字在每个组合中只能使用一次. ...

  2. 17 安全字符串 System.Security.SecureString

  3. UI自动化前置代码

    一.前置代码: #导入包selenium from selenium import webdriverimport time#创键一个火狐对象driver=webdriver.Firefox()#防问 ...

  4. [USACO17FEB]Why Did the Cow Cross the Road III G (树状数组,排序)

    题目链接 Solution 二维偏序问题. 现将所有点按照左端点排序,如此以来从左至右便满足了 \(a_i<a_j\) . 接下来对于任意一个点 \(j\) ,其之前的所有节点都满足 \(a_i ...

  5. 2、投资之基金 - IT人思维之投资

    笔者曾经对基金进行投资,但是当时对基金不是很了解,只是为了投资而去投资.现在,笔者对基金的投资有了更深入的了解认识,所以就有了本文. 基金投资在国内还是挺流行的,虽然其是从国外引进来的概念经验,但是国 ...

  6. 2017年度最具商业价值人工智能公司TOP50 榜单发布

    2017年度最具商业价值人工智能公司TOP50 榜单发布 未来最有赚钱潜力的50个人工智能项目都在这里了. 经过了60年的发展,人工智能在2017年,正式走向应用的元年. 从今年起,人工智能首次被写入 ...

  7. react-navigation 实战

    npm install --save react-navigation 1.测试TabNavigator.StackNavigator和DrawerNavigator (1)新建HomeScreen. ...

  8. TimeInOfficePresent

    w x <- c(52, 30, 10, 8)labels <- c("分析思考", "写代码.调试", "沟通", " ...

  9. 【CDN+】 Hbase入门 以及Hbase shell基础命令

    前言 大数据的基础离不开Hbase, 本文就hbase的基础概念,特点,以及框架进行简介, 实际操作种需要注意hbase shell的使用. Hbase  基础 官网:https://hbase.ap ...

  10. tomcat 迁移到weblogic 问题

    问题1: Caused by: java.lang.UnsupportedClassVersionError: com/audaque/datadiscovery/soap/service/impl/ ...