使用socket设计一个同步异步的python框架

Posted achjiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用socket设计一个同步异步的python框架相关的知识,希望对你有一定的参考价值。

 

使用socket搭建一个web框架实现同步异步处理IO请求,代码实现如下:

技术分享图片
  1   1 # coding=utf-8
  2   2 # Time : 2018/11/2 21:38
  3   3 # Author : achjiang
  4   4 # File : web_frame.py
  5   5 
  6   6 import socket
  7   7 import select
  8   8 
  9   9 
 10  10 class HttpRequest(object):
 11  11     """
 12  12     用户封装用户请求信息
 13  13     """
 14  14 
 15  15     def __init__(self, content):
 16  16         """
 17  17         :param content:用户发送的请求数据:请求头和请求体
 18  18         """
 19  19         self.content = content
 20  20 
 21  21         self.header_bytes = bytes()
 22  22         self.body_bytes = bytes()
 23  23 
 24  24         self.header_dict = {}
 25  25 
 26  26         self.method = ""
 27  27         self.url = ""
 28  28         self.protocol = ""
 29  29 
 30  30         self.initialize()
 31  31         self.initialize_headers()
 32  32 
 33  33     def initialize(self):
 34  34         temp = self.content.split(b

, 1)
 35  35         if len(temp) == 1:
 36  36             self.header_bytes += temp
 37  37         else:
 38  38             h, b = temp
 39  39             self.header_bytes += h
 40  40             self.body_bytes += b
 41  41 
 42  42     @property
 43  43     def header_str(self):
 44  44         return str(self.header_bytes, encoding=utf-8)
 45  45 
 46  46     def initialize_headers(self):
 47  47         headers = self.header_str.split(
)
 48  48         first_line = headers[0].split( )
 49  49         if len(first_line) == 3:
 50  50             self.method, self.url, self.protocol = headers[0].split( )
 51  51             for line in headers:
 52  52                 kv = line.split(:)
 53  53                 if len(kv) == 2:
 54  54                     k, v = kv
 55  55                     self.header_dict[k] = v
 56  56 
 57  57 # class Future(object):
 58  58 #     def __init__(self):
 59  59 #         self.result = None
 60  60 
 61  61 
 62  62 def main(request):
 63  63     return "main"
 64  64 
 65  65 
 66  66 def index(request):
 67  67     return "indexasdfasdfasdf"
 68  68 
 69  69 
 70  70 routers = [
 71  71     (/main/, main),
 72  72     (/index/, index),
 73  73 ]
 74  74 
 75  75 
 76  76 def run():
 77  77     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 78  78     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 79  79     sock.bind(("127.0.0.1", 9999,))
 80  80     sock.setblocking(False)
 81  81     sock.listen(128)
 82  82 
 83  83     inputs = []
 84  84     inputs.append(sock)
 85  85     while True:
 86  86         rlist, wlist, elist = select.select(inputs, [], [], 0.05)
 87  87         for r in rlist:
 88  88             if r == sock:
 89  89                 """新请求到来"""
 90  90                 conn, addr = sock.accept()
 91  91                 conn.setblocking(False)
 92  92                 inputs.append(conn)
 93  93             else:
 94  94                 """客户端发来数据"""
 95  95                 data = b""
 96  96                 while True:
 97  97                     try:
 98  98                         chunk = r.recv(1024)
 99  99                         data = data + chunk
100 100                     except Exception as e:
101 101                         chunk = None
102 102                     if not chunk:
103 103                         break
104 104                 # data进行处理:请求头和请求体
105 105                 request = HttpRequest(data)
106 106                 # 1. 请求头中获取url
107 107                 # 2. 去路由中匹配,获取指定的函数
108 108                 # 3. 执行函数,获取返回值
109 109                 # 4. 将返回值 r.sendall(b‘alskdjalksdjf;asfd‘)
110 110                 import re
111 111                 flag = False
112 112                 func = None
113 113                 for route in routers:
114 114                     if re.match(route[0], request.url):
115 115                         flag = True
116 116                         func = route[1]
117 117                         break
118 118                 if flag:
119 119                     result = func(request)
120 120                     r.sendall(bytes(result, encoding=utf-8))
121 121                 else:
122 122                     r.sendall(b"404")
123 123 
124 124                 inputs.remove(r)
125 125                 r.close()
126 126 
127 127 
128 128 if __name__ == __main__:
129 129     run()
View Code

 

以上是关于使用socket设计一个同步异步的python框架的主要内容,如果未能解决你的问题,请参考以下文章

python epoll实现异步socket

如何在python中选择异步或同步方法变体?

Python之并发并行阻塞非租塞同步异步IO多路复用

Python异步编程之web框架 异步vs同步 文件IO任务压测对比

自定义异步IO框架

一图看懂Spring Boot 异步框架