类HTTPServer

HTTPServer在整个框架中最主要的作用是做TCP层和应用层之间的隔离,为IO和具体应用层搭建了桥梁。

响应流程图:

类HTTPServer_第1张图片

从功能上看,它最主要做的事情通俗的讲就是监听端口上的动静(主要是TCP层),当客户端向服务器某个端口发起请求被其监听到之后,通过handle_stream来做对应的处理,其中最终调用了HTTP1ServerConnection类的start_serving方法,在这个方法里最终回调了HTTPServer实现的start_request接口,进入了_ServerRequestAdapter类,在此类初始化的时候判断HTTPServer类里的request_callback是不是一个HTTPServerConnectionDelegate(显然很多时候我们都定义其继承类Application),是的话调用此delegate的start_request方法。

class HTTPServer(TCPServer, httputil.HTTPServerConnectionDelegate):
    def __init__(self, request_callback, no_keep_alive=False, io_loop=None,
                 xheaders=False, ssl_options=None, protocol=None,
                 decompress_request=False,
                 chunk_size=None, max_header_size=None,
                 idle_connection_timeout=None, body_timeout=None,
                 max_body_size=None, max_buffer_size=None):
        self.request_callback = request_callback
        #...

    def handle_stream(self, stream, address):
        context = _HTTPRequestContext(stream, address,
                                      self.protocol)
        conn = HTTP1ServerConnection(
            stream, self.conn_params, context)
        self._connections.add(conn)
        conn.start_serving(self)
    def start_request(self, server_conn, request_conn):
        return _ServerRequestAdapter(self, server_conn, request_conn)
        
##httpserver继承TCPserver中的listen启动监听,在启动过程中绑定socket,当socket上出现新连接请求的时候,启动handle_stream做对应处理
    def listen(self, port, address=""):
        sockets = bind_sockets(port, addrebind_socketsss=address)
        self.add_sockets(sockets)

    def add_sockets(self, sockets):  
        if self.io_loop is None:
            self.io_loop = IOLoop.current()
        for sock in sockets:
            self._sockets[sock.fileno()] = sock
            add_accept_handler(sock, self._handle_connection,  
                               io_loop=self.io_loop)
                               
    def _handle_connection(self, connection, address):
        #....
            self.handle_stream(stream, address)
            
##############class HTTP1ServerConnection(object):            
    def start_serving(self, delegate):
        assert isinstance(delegate, httputil.HTTPServerConnectionDelegate)
        self._serving_future = self._server_request_loop(delegate)
        self.stream.io_loop.add_future(self._serving_future,
                                       lambda f: f.result())

    @gen.coroutine
    def _server_request_loop(self, delegate):
       #...
                conn = HTTP1Connection(self.stream, False,
                                       self.params, self.context)
                request_delegate = delegate.start_request(self, conn)
               
###########真正将客户端请求回调到对应的handler的地方               
class _ServerRequestAdapter(httputil.HTTPMessageDelegate):
    def __init__(self, server, server_conn, request_conn):
        #...
        if isinstance(server.request_callback,
                      httputil.HTTPServerConnectionDelegate):
            self.delegate = server.request_callback.start_request(
                server_conn, request_conn)


还记得这个例子么:

if __name__=="__main__":
    tornado.options.parse_command_line()   
    
    #实例了一个Application,其中有两个RequestHandler对:"/" -- IndexHandler,'/poem' -- PoemPageHandler
    app = tornado.web.Application(
        handlers=[(r"/", IndexHandler), (r'/poem', PoemPageHandler)],
        template_path=os.path.join(os.path.dirname(__file__), "templates")
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

  用户定义好了两个RequestHandler,分别对应输入流里的”/“ 和‘/poem‘,将此元组初始化Application,并将其作为参数传递给http_server, http_server启动监听,当监听到客户端传来的输入流,截取其中的header,并将其转入Application的start_request处理。

    def start_request(self, server_conn, request_conn):
        # Modern HTTPServer interface
        return _RequestDispatcher(self, request_conn)

###then 我们来到这个具体实现的类:

class _RequestDispatcher(httputil.HTTPMessageDelegate):
    
    def headers_received(self, start_line, headers):
        self.set_request(httputil.HTTPServerRequest(
            connection=self.connection, start_line=start_line, headers=headers))
        if self.stream_request_body:
            self.request.body = Future()
            return self.execute()

    def _find_handler(self):    
        app = self.application
        handlers = app._get_host_handlers(self.request)
        if not handlers:
            self.handler_class = RedirectHandler
            self.handler_kwargs = dict(url="%s://%s/" % (self.request.protocol, app.default_host))
            return
        for spec in handlers:
            match = spec.regex.match(self.request.path)
            if match:
                self.handler_class = spec.handler_class
                self.handler_kwargs = spec.kwargs
                if spec.regex.groups:
                   
                    if spec.regex.groupindex:
                        self.path_kwargs = dict(
                            (str(k), _unquote_or_none(v))
                            for (k, v) in match.groupdict().items())
                    else:
                        self.path_args = [_unquote_or_none(s)
                                          for s in match.groups()]
                return
        if app.settings.get('default_handler_class'):
            self.handler_class = app.settings['default_handler_class']
            self.handler_kwargs = app.settings.get(
                'default_handler_args', {})
        else:
            self.handler_class = ErrorHandler
            self.handler_kwargs = dict(status_code=404)


    def execute(self):
   
        if not self.application.settings.get("compiled_template_cache", True):
            with RequestHandler._template_loader_lock:
                for loader in RequestHandler._template_loaders.values():
                    loader.reset()
        if not self.application.settings.get('static_hash_cache', True):
            StaticFileHandler.reset()

        self.handler = self.handler_class(self.application, self.request,
                                          **self.handler_kwargs)
        transforms = [t(self.request) for t in self.application.transforms]

        if self.stream_request_body:
            self.handler._prepared_future = Future()

你可能感兴趣的:(类HTTPServer)