框架一

自定义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. windows cmd bat处理文件

    bat中输入: @echo offtitle 正在承载无线网络....netsh wlan start hostednetworknetsh wlan show hostednetworkecho 启 ...

  2. POJ 3784 Running Median (动态中位数)

    题目链接:http://poj.org/problem?id=3784 题目大意:依次输入n个数,每当输入奇数个数的时候,求出当前序列的中位数(排好序的中位数). 此题可用各种方法求解. 排序二叉树方 ...

  3. Xcode模拟器快捷键

    command + 左右 = 横竖屏旋转 command + H + H = 切入层级后台模式

  4. C#第一个程序Helloworld

  5. Linux内核设计与实现 总结笔记(第五章)系统调用

    系统调用 内核提供了用户进程和内核交互的接口,使得应用程序可以受限制的访问硬件设备. 提供这些接口主要是为了保证系统稳定可靠,避免应用程序恣意妄行. 一.内核通信 系统调用在用户空间进程和硬件设备之间 ...

  6. 历时小半年总结之JAVA

    一.JavaSE 1.多线程 (1).进程与线程的区别? 答:进程是所有线程的集合,每一个线程是进程中的一条执行路径,线程只是一条执行路径. (2).为什么要用多线程? 答:提高程序效率 (3).多线 ...

  7. 求超大文件上传方案( Java )

    最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表 ...

  8. js请求解析xml

    xml数据 <?xml version="1.0" encoding="utf-8"?> <table> <node name=& ...

  9. 代码片段快捷键 CodeSnippets

    CodeSnippets https://github.com/jaydee3/CodeSnippets These are my Xcode 4 CodeSnippets. To use them, ...

  10. 基于ES6的tinyJquery

    原文地址:Bougie的博客 jQuery作为曾经Web前端的必备利器,随着MVVM框架的兴起,如今已稍显没落.但它操作DOM的便利性无出其右.我用ES6写了一个基于class简化版的jQuery,包 ...