Tornado 学习笔记13 TCPServer

     为了实现TCPServer的功能,定义一个类用于继承TCPServer并实现handle_stream方法。HttpServer就是一个很好的例子。

13.1 构造函数

def __init__(self, io_loop=None, ssl_options=None, max_buffer_size=None,
             read_chunk_size=None):
    self.io_loop = io_loop
    self.ssl_options = ssl_options
    self._sockets = {}  # fd -> socket object
    self._pending_sockets = []
    self._started = False
    self.max_buffer_size = max_buffer_size
    self.read_chunk_size = read_chunk_size

    # Verify the SSL options. Otherwise we don't get errors until clients
    # connect. This doesn't verify that the keys are legitimate, but
    # the SSL module doesn't do that until there is a connected socket
    # which seems like too much work
    if self.ssl_options is not None and isinstance(self.ssl_options, dict):
        # Only certfile is required: it can contain both keys
        if 'certfile' not in self.ssl_options:
            raise KeyError('missing key "certfile" in ssl_options')

        if not os.path.exists(self.ssl_options['certfile']):
            raise ValueError('certfile "%s" does not exist' %
                             self.ssl_options['certfile'])
        if ('keyfile' in self.ssl_options and
                not os.path.exists(self.ssl_options['keyfile'])):
            raise ValueError('keyfile "%s" does not exist' %
                             self.ssl_options['keyfile'])

     实现流程如下:

(1) 设置属性。

(2) 判断是否支持SLL,如果支持,判断证书文件以及秘钥文件是否存在。

13.2 监听 listen

          开启指定端口的接收连接。

          为了监听多个端口时,这个方法可能会被调用多次。这个方法会立即起作用,不需要调用TCPServer.start方法。但是,还是有必要启动IOLoop。

def listen(self, port, address=""):
    """Starts accepting connections on the given port.

    This method may be called more than once to listen on multiple ports.
    `listen` takes effect immediately; it is not necessary to call
    `TCPServer.start` afterwards.  It is, however, necessary to start
    the `.IOLoop`.
    """
    sockets = bind_sockets(port, address=address)
    self.add_sockets(sockets)

          调用bind_sockets方法来获得sockets集合对象。调用add_sockets方法循环处理每一个sockets对象,主要注册socket建立连接后的处理回调函数。

13.3 添加sockets (add_sockets)


def add_sockets(self, sockets):
    """Makes this server start accepting connections on the given sockets.

    The ``sockets`` parameter is a list of socket objects such as
    those returned by `~tornado.netutil.bind_sockets`.
    `add_sockets` is typically used in combination with that
    method and `tornado.process.fork_processes` to provide greater
    control over the initialization of a multi-process server.
    """
    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)

         针对每一个socket, 注册socket建立连接后的处理回调函数,回调函数为内部方法_handle_connection。

13.4 关闭服务器(stop)

def stop(self):
    """Stops listening for new connections.

    Requests currently in progress may still continue after the
    server is stopped.
    """
    for fd, sock in self._sockets.items():
        self.io_loop.remove_handler(fd)
        sock.close()

         关闭服务器,停止监新的请求连接。在服务器关闭之后,当前正在处理的请求会继续执行。

        执行逻辑就是,对服务器中所有的sockets对象,调用两个方法,一个是移除io_loop中的处理回调函数,一个是关闭socket.

 

13.5 socket的建立连接后的回调函数 _handle_connection

           socket处理请求时,这个方法是回调函数,用来处理请求流。如果请求是SSL请求,则初始化SSLIOStream类,如果不是SSL请求,则初始化IOStream类。初始化Stream之后,调用handle_stream方法来处理stream.handler_stream方法一般由TCPServer的子类实现,比如HttpServer就有具体的实现。
posted @ 2015-12-29 17:09  廖飞  阅读(791)  评论(0编辑  收藏  举报