PYTHON中的动态服务器和WSGI协议

来源:互联网 发布:id软件 编辑:程序博客网 时间:2024/06/03 18:50

静态服务器加载的是一个静态html页面,或者是存在服务器的中的静态数据,动态服务器是,当客户端发送一个请求,服务器拿到这个请求找到相关的程序代码执行,将执行结果返回给客户端的一个过程
下面看看动态服务器执行的过程

这里写图片描述

WSGI

怎么在你刚刚建立的web服务器上运行一个Django应用和一个Flask应用呢。如何做不做任何改变而适应不同的web架构呢。
在以前,选择PYTHON WEB架构会限制可用的web服务器,反之亦然。
如果架构和服务器可以协同工作就好了
那么怎么不修改服务器架构代码而确保可以运行web服务器呢,答案是Python Web server Gataway Interface简称WSGI

这里写图片描述

WSGI的接口定义非常简单,他只要求Web开发者实现一个函数。就可以响应web请求。我们来看一下最简单的代码

def applicaiton(env, start_response):    # env.get("Method")    # env.get("PATH_INFO")    # env.get("QUERY_STRING")    status = "200 OK"    headers = [        ("Content-Type", "text/plain")    ]    start_response(status, headers)    return time.ctime()

下面的代码演示一个动态服务器的代码

import socketimport reimport sysfrom multiprocessing import Process# 设置静态文件根目录HTML_ROOT_DIR = "./html"WISG_PYTHON_DIR ='./wsgipython'class HTTPServer(object):    """"""    def __init__(self):        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)    def start(self):        self.server_socket.listen(128)        while True:            client_socket, client_address = self.server_socket.accept()            # print("[%s, %s]用户连接上了" % (client_address[0],client_address[1]))            print("[%s, %s]用户连接上了" % client_address)            handle_client_process = Process(target=self.handle_client, args=(client_socket,))            handle_client_process.start()            client_socket.close()    def start_response(self,status,headers):        response_headers ='HTTP/1.1 '+ status+'\r\n'        for header in headers:            response_headers+='%s: %s\r\n'%header        self.response_headers = response_headers    def handle_client(self, client_socket):        """处理客户端请求"""        # 获取客户端请求数据        request_data = client_socket.recv(1024)        print("request data:", request_data)        request_lines = request_data.splitlines()        for line in request_lines:            print(line)        # 解析请求报文        # 'GET / HTTP/1.1'        request_start_line = request_lines[0]        # 提取用户请求的文件名        print("*" * 10)        print(request_start_line.decode("utf-8"))        file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1)        # 提取用户的请求方式        method = re.match(r'(\w+) +/[^ ]* ',request_start_line.decode("utf-8")).group(1)        if file_name.endswith('.py'):            # //给一个包名或者模块名,就可以返回一个模块            #env是我们解析请求报文所拿到的相关数据;实际我们需要传入更多的参数。            m= __import__(file_name[1:-3])            env={                'PATH_INFO':file_name,                'METHOD':method            }            #env是本次请求的相关信息,。            response_body=m.applicaiton(env,self.start_response)            response = self.response_headers+'\r\n'+response_body        else:            if "/" == file_name:                file_name = "/index.html"                # 打开文件,读取内容                try:                    file = open(HTML_ROOT_DIR + file_name, "rb")                except IOError:                    response_start_line = "HTTP/1.1 404 Not Found\r\n"                    response_headers = "Server: My server\r\n"                    response_body = "The file is not found!"                else:                    file_data = file.read()                    file.close()                    # 构造响应数据                    response_start_line = "HTTP/1.1 200 OK\r\n"                    response_headers = "Server: My server\r\n"                    response_body = file_data.decode("utf-8")                response = response_start_line + response_headers + "\r\n" + response_body                print("response data:", response)        # 向客户端返回响应数据        client_socket.send(bytes(response, "utf-8"))        # 关闭客户端连接        client_socket.close()    def bind(self, port):        self.server_socket.bind(("", port))def main():    sys.path.insert(1,WISG_PYTHON_DIR)    http_server = HTTPServer()    # http_server.set_port    http_server.bind(8200)    http_server.start()if __name__ == "__main__":    main()

我们需要动态执行代码,我们写在一个.py文件中,我现在给这个文件卸载ctime.py

# coding:utf-8import time# "/ctime.py?timezone=e8"# "/ctime.py?timezone=e1"#application的返回值会作为服务器返回报文中的响应体部分。#wsg协议中要决定,响应头头报文。def applicaiton(env, start_response):    # env.get("Method")    # env.get("PATH_INFO")    # env.get("QUERY_STRING")    status = "200 OK"    headers = [        ("Content-Type", "text/plain")    ]    start_response(status, headers)    return time.ctime()

当我们在浏览器地址栏输入http://127.0.0.1:8200/ctime.py,就可以显示了一个时间信息。

原创粉丝点击