分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

Tornado----自定义异步非阻塞Web框架:Snow

发布时间:2023-09-06 01:11责任编辑:郭大石关键词:Web

Python的Web框架中Tornado以异步非阻塞而闻名。本篇将使用200行代码完成一个微型异步非阻塞Web框架:Snow。

一、源码

本文基于非阻塞的Socket以及IO多路复用从而实现异步非阻塞的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 ????@property101 ????def ready(self):102 ????????return self._ready103 104 105 class TimeoutFuture(Future):106 ????"""107 ????异步非阻塞超时108 ????"""109 ????def __init__(self, timeout):110 ????????super(TimeoutFuture, self).__init__(callback=None)111 ????????self.timeout = timeout112 ????????self.start_time = time.time()113 114 ????@property115 ????def ready(self):116 ????????current_time = time.time()117 ????????if current_time > self.start_time + self.timeout:118 ????????????self._ready = True119 ????????return self._ready120 121 122 class Snow(object):123 ????"""124 ????微型Web框架类125 ????"""126 ????def __init__(self, routes):127 ????????self.routes = routes128 ????????self.inputs = set()129 ????????self.request = None130 ????????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] = yielded163 ????????????????self.polling_callback()164 165 ????????except Exception as e:166 ????????????pass167 ????????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 ????????????????continue179 ????????????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 = None194 ????????for route in self.routes:195 ????????????if re.match(route[0], self.request.url):196 ????????????????func = route[1]197 ????????????????break198 ????????if not func:199 ????????????return HttpNotFound()200 ????????else:201 ????????????return func(self.request)
snow.py

二、使用

1. 基本使用

 1 from snow import Snow 2 from snow import HttpResponse 3 ??4 ??5 def index(request): 6 ????return HttpResponse(‘OK‘) 7 ??8 ??9 routes = [10 ????(r‘/index/‘, index),11 ]12 ?13 app = Snow(routes)14 app.run(port=8012)

2.异步非阻塞:超时

 1 from snow import Snow 2 from snow import HttpResponse 3 from snow import TimeoutFuture 4 ??5 request_list = [] 6 ??7 ??8 def async(request): 9 ????obj = TimeoutFuture(5)10 ????yield obj11 ?12 ?13 def home(request):14 ????return HttpResponse(‘home‘)15 ?16 ?17 routes = [18 ????(r‘/home/‘, home),19 ????(r‘/async/‘, async),20 ]21 ?22 app = Snow(routes)23 app.run(port=8012)

3.异步非阻塞:等待

基于等待模式可以完成自定制操作

 1 from snow import Snow 2 from snow import HttpResponse 3 from snow import Future 4 ??5 request_list = [] 6 ??7 ??8 def callback(request, future): 9 ????return HttpResponse(future.value)10 ?11 ?12 def req(request):13 ????obj = Future(callback=callback)14 ????request_list.append(obj)15 ????yield obj16 ?17 ?18 def stop(request):19 ????obj = request_list[0]20 ????del request_list[0]21 ????obj.set_result(‘done‘)22 ????return HttpResponse(‘stop‘)23 ?24 ?25 routes = [26 ????(r‘/req/‘, req),27 ????(r‘/stop/‘, stop),28 ]29 ?30 app = Snow(routes)31 app.run(port=8012)

Tornado----自定义异步非阻塞Web框架:Snow

原文地址:http://www.cnblogs.com/wangyongsong/p/7526646.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved