web框架的本质(socket,WSGI)

众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端

 

SOCKET实现

_author__ = "Burgess Zheng"
import socket
def handle_request(client):
    buf = client.recv(1024)  #接收请求
    client.send(bytes("HTTP/1.1 200 OK\r\n\r\n",encoding='utf-8'))
    client.send(bytes("Hello,Seven",encoding='utf-8'))
                            #发送请求
                            #bytes():转换成bytes类型
                            #当然直接encoding不用谢bytes也行,但是按照标准比较不会出错
                            #相当于 str(1)转换字符串
                            #相当于list((111,))转换成列表
                            #相当于bytes('sdfsd',)转换成bytes

def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#创建socket服务端
    sock.bind(('0.0.0.0', 8000))#监听端口
    sock.listen(5)#最大连接数

    while True: #循环
        connection, address = sock.accept() #只要有人连接获取该连接
                                     # connection:链接标记位, address:对方的地址
        handle_request(connection)#执行handle_reques处理函数
        connection.close()#连接断开 #也就是有人访问了该服务端,服务端返回数据后自动断开
if __name__ == '__main__':
    main()  #执行该函数

执行结果:

上述通过socket来实现了其本质,而对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:DjangoFlaskweb.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。

WSGIWeb Server Gateway Interface)是一种规范,它定义了使用python编写的web appweb server之间接口格式,实现web appweb server间的解耦。

python标准库提供的独立WSGI服务器称为wsgiref

试验调用Python的wsgiref模块创建socket服务端

整个生命周期简单理解:

    1.用户访问指定IP端口

    2.服务端接收从头部信息提取出访问的url进行判断是否有效

    3.访问的url有效就调用对应函数处理

    4.处理函数二进制打开本地html文件进行赋值返回给用户(如果html内容需要替换也可以替换以后进行返回给用户)

main_wsgiref(wsgiref模块实现服务端)

__author__ = "Burgess Zheng"

from wsgiref.simple_server import make_server
# 导入了WSGI socket模块
from Controller import account
#导入自定义的account函数模块

ULR_DICT = {
    "/index": account.handle_index,
    "/date": account.handle_date,
}
# 字典模式:字符串:函数执行的结果
# account.handle_index 获取account模块里面的handle_index函数

def RunServer(environ, start_response):
    # emvorpn:封装了客户端发来的所有的数据
    #start_response 封装要返回给用户的数据、响应头状态
    print(1)
    start_response('200 OK', [('Content-Type', 'text/html')])
    #返回给用户的响应头状态
    current_url = environ['PATH_INFO']
    #获取用户的想要访问的url,赋值到current_url
    func = None
    # 默认func =None
    if current_url in ULR_DICT:
    # 假如用户访问的url存在于ULR_DICT字典内,执行下面操作
        func = ULR_DICT[current_url] #获取了相应返回用户数据
    if func: #如果func获取到了,执行下面返回给用户数据
        return func()
    else:   #否则报错
        return['<h1>404</h1>'.encode('utf-8')]
#这样如果新增用户访问路径的话就无需再更改该地方了




if __name__ == '__main__':
    httpd = make_server('', 8000, RunServer)
    # 创建WIGI服务端 3个形参 分别是:监听的IP,端口,处理函数
    print("Serving HTTP on port 8000...")
    httpd.serve_forever()
    # 运行该服务端
    # 运行以后,1帮你创建一个socket服务端,2.客户连接上以后就会触发RunServer函数

Controller/account.py(用户请求进行处理)

__author__ = "Burgess Zheng"

def handle_index():
    import time #引入时间模块
    v = str(time.time()) #获取当前时间
    f = open('View/index.html',mode='rb')
    #二进制读取打开View目录的index.html文件,
    data = f.read()
    # 读取该文件内容,然后内容赋值给data
    f.close()#关闭该文件
    data = data.replace(b'@uuuuu',v.encode('utf-8'))
    # data.replace替换内容  内容@uuuuu 替换成 二进制当前时间(v)
    return [data,]
    #返回该data数据
def handle_date():
    f = open('View/date.html', mode='rb')
    data = f.read()
    f.close()
    return [data,]

View/date.html  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>Date</h1>
</body>
</html>

View/index.html  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>Index @uuuuu</h1>
</body>
</html>

启动main_wsgiref:

浏览器访问:

猜你喜欢

转载自blog.csdn.net/Burgess_zheng/article/details/86496202