Python模块WSGI使用详解

  

WSGI (Web服务器网关接口):Web服务网关接口,是Python中定义的服务器程序和应用程序之间的接口。
  

  

Web程序开发中,一般分为服务器程序和应用程序。服务器程序负责对套接字服务的数据进行封装和整理,而应用程序则负责对Web请求进行逻辑处理。
  

  

Web应用本质上也是一个套接字服务器,用户的浏览器就是一个套接字客户端。
  

  

我们先用套接字编程实现一个简单的Web服务器:
  

        进口套接字      def handle_request(客户端):   buf=client.recv (1024)   打印(buf)   味精=癏TTP/1.1 200 OK \ r \ n \ r \ n”# HTTP头信息   客户端。发送((' % s ' %味精).encode ())   味精=癏ello, World !”   客户端。发送((' % s ' %味精).encode ())      def main ():   ip_port=(“localhost”, 8000年)   袜子=socket.socket(插座。AF_INET socket.SOCK_STREAM)   sock.bind (ip_port)   sock.listen (5)      而真正的:   康涅狄格州,addr=sock.accept ()   handle_request(康涅狄格州)   conn.close ()      if __name__==癬_main__”:   main ()   之前      

上述代码中,主要()函数就是服务器函数,handle_request()就是应用程序。
  下面我们再用python的wsgiref模块来实现跟上述代码一样的Web服务器:
  

        从wsgiref。simple_server进口make_server      def handle_request (env, res):   res (“200 OK”,(“内容类型”,“text/html”)))   身体=" & lt; h2> Hello World ! & lt;/h2>”   返回(body.encode (“utf - 8”))      if __name__==癬_main__”:   httpd=make_server(" ", 8000年,handle_request)   打印(“http服务>   if __name__==癬_main__”:   httpd=make_server(" ", 8000年,handle_request)   打印(“http服务>   def make_server(主机、端口、应用,server_class=WSGIServer handler_class=WSGIRequestHandler):   ”““创建一个新的WSGI服务器听>   # BaseServer类的__init__()函数:   def __init__(自我、server_address RequestHandlerClass):   ”“”的构造函数。可以延长,不要覆盖。”“”   自我。server_address=server_address   自我。RequestHandlerClass=RequestHandlerClass   自我。__is_shut_down=threading.Event ()   自我。__shutdown_request=False   之前            # TCPServer类的__init__()函数:   def __init__(自我、server_address RequestHandlerClass bind_and_activate=True):   ”“”的构造函数。可以延长,不要覆盖。”“”   BaseServer。__init__(自我、server_address RequestHandlerClass)   自我。套接字=socket.socket (self.address_family self.socket_type)   如果bind_and_activate:   试一试:   self.server_bind ()   self.server_activate ()   除了:   self.server_close ()   提高   之前      

TCPServer类的初始化函数还调用了server_bind(自我),server_bind(自我)两个函数:
  

        def server_bind(自我):   ”““由构造函数调用绑定套接字。可能覆盖。”“”   如果self.allow_reuse_address:   self.socket.setsockopt(套接字。SOL_SOCKET,插座。SO_REUSEADDR, 1)   self.socket.bind (self.server_address)   自我。server_address=self.socket.getsockname ()   def self.server_activate(自我):   ”“”由构造函数调用激活服务器。可能覆盖。”“”   self.socket.listen (self.request_queue_size)   之前      

可以看到server.bind()函数调用了socket.bind()函数,而server_activate()调用了socket.listen()函数:
  

  

3, server.set_app(应用程序),此处传入网络请求的处理逻辑:
  

        def set_app(自我、应用):   自我。应用=应用   之前      

4, httpd.serve_forever()函数调用BaseServer类的_handle_request_noblock()函数处理多路请求:
  

        def _handle_request_noblock(自我):   试一试:   请求,client_address=self.get_request () # get_request()调用了socket.accept()函数   除了OSError:   返回   如果自我。verify_request(请求,client_address):   试一试:   自我。client_address process_request(请求)   除了:   自我。client_address handle_error(请求)   self.shutdown_request(请求)   其他:   self.shutdown_request(请求)         

Python模块WSGI使用详解