Я только что быстро взглянул на источник, и, похоже, он работает так:
Tornado не контролирует сами сокеты, он передает это задание в операционную систему, используя epoll
(Linux) или select
. Вызов self.io_loop.add_handler
просто добавляет обратный вызов, когда новое соединение доступно.
Клиентские подключения устанавливаются self._handle_events
, что создает новый HTTPConnection
для каждого нового подключения, полученного сокетом. Коммуникационный сокет, используемый каждым HTTPConnection
, является новым сокетом, созданным путем вызова sock.accept()
. Сервер продолжает принимать соединения в том же сокете, что и раньше.
итого в итоге:
- Да, io_loop вызывает
self._handle_events
при обнаружении нового соединения в сокете.
- Нет, сокет повторно используется для новых подключений. Вместо этого для каждого клиента создается новый объект
HTTPConnection
с отдельным сокетом для связи.
- io_loop не нужно активно контролировать сокет. Он передает обязанности операционной системе, используя
epoll
или select
. Фактическое общение с клиентами осуществляется объектами HTTPConnection
.
Я думаю, что ключевым моментом для понимания является то, что сокет здесь используется только для приема новых соединений. Когда соединение принято с использованием sock.accept()
, возвращается новый сокет для связи, который затем присоединяется к объекту HTTPConnection
.