ки по рецепту.
Существуют два других популярных фреймворка, основанных на событиях, — tornado (http://
www.tornadoweb.org/) и gunicorn (http://gunicorn.org/). Они помогают обрабатывать события
на низком уровне, а также предоставляют быстрый веб-сервер. Их стоит рассмотреть, если
вы хотите создать быстрый сайт, не применяя традиционные веб-серверы вроде Apache.
Конкуренция
311
twisted
twisted (http://twistedmatrix.com/trac/) — это асинхронный фреймворк для работы
с сетями, управляемый событиями. Вы подключаете функции к событиям вроде
получения данных или закрытия соединения, и эти функции вызываются, когда
событие случается. Эти функции называются функциями обратного вызова, и если
вы уже писали код на языке JavaScript, он может показаться вам знакомым. Если же
он для вас в новинку, то может показаться вывернутым наизнанку. Некоторым
разработчикам может оказаться труднее поддерживать код, основанный на функ-
циях обратного вызова, по мере роста приложения.
Как и gevent, twisted еще не был портирован на Python 3. В этом разделе мы
будем использовать установщик и интерактивный интерпретатор Python 2. Чтобы
установить фреймворк, введите следующую команду:
$ pip2 install twisted
twisted — это крупный пакет, который поддерживает множество интернет-про-
токолов на базе TCP и UDP. Для краткости мы рассмотрим небольшой сервер
и клиент, созданные на базе примеров для twisted (http://bit.ly/twisted-ex). Сначала
рассмотрим сервер, knock_server.py (обратите внимание на синтаксис Python 2 для
функции print()):
from twisted.internet import protocol, reactor
class Knock(protocol.Protocol):
def dataReceived(self, data):
print 'Client:', data
if data.startswith("Knock knock"):
response = "Who's there?"
else:
response = data + " who?"
print 'Server:', response
self.transport.write(response)
class KnockFactory(protocol.Factory):
def buildProtocol(self, addr):
return Knock()
reactor.listenTCP(8000, KnockFactory())
reactor.run()
Теперь взглянем на его верного компаньона, knock_client.py:
from twisted.internet import reactor, protocol
class KnockClient(protocol.Protocol):
def connectionMade(self):
self.transport.write("Knock knock")
def dataReceived(self, data):
if data.startswith("Who's there?"):
response = "Disappearing client"
312