Difference between revisions of "Twisted"
m (→Пример клиентского приложения: отступы) |
(→Пример клиентского приложения: ссылка на глоссарий) |
||
Line 38: | Line 38: | ||
me = jid.JID("greutly@swissjabber.ch/TwistedWords") | me = jid.JID("greutly@swissjabber.ch/TwistedWords") | ||
− | # Так как бот -- это клиентское приложение, то и factory (см | + | # Так как бот -- это клиентское приложение, то и factory (см [http://twistedmatrix.com/projects/core/documentation/howto/glossary.html глоссарий]) |
# тоже будет клиентским. Библиотека twisted.words.protocols.jabber.client | # тоже будет клиентским. Библиотека twisted.words.protocols.jabber.client | ||
# предоставляет класс для создания factory Jabber-клиентов. | # предоставляет класс для создания factory Jabber-клиентов. |
Revision as of 13:13, 24 May 2007
Twisted | |
---|---|
Информация | |
Адрес: | http://twistedmatrix.com/trac/ |
Язык: | Python |
Реализация стандартов | |
Использование | |
Программы, использующие Twisted |
Twisted -- framework для написания сетевых приложений. Предоставляет механизмы для легкой реализации сетевого сервера и клиента. Есть классы облегчающие реализацию своего протокола, а также уже реализована обработка большого числа существующих протоколов, в том числе и XML-потока Jabber-а.
Но работа Twisted не ограничивается только сетью. Этот фреймворк облегчает создание расширяемых с помощью плагинов программ, конструирование многосервисных программ, создание единой авторизации пользователей между сервисами и многое другое.
Contents
Для начинающего Twisted-разработчика
В отличии от многих других библиотек и фреймворков для реализации Jabber-приложений, в twisted-e обработка нескольких клиентских соединений производится не через потоки или процессы, а через конечный автомат (FSM). Это заставляет при написании приложения придерживаться нескольких правил:
- Функция не должна долго думать. Так как практически все соединения обрабатываются в одном потоке и в одном цикле, то каждая пауза сказывается на всех. Поэтому "долгие" задачи должны быть выделены в отдельный поток, который в конце работы передаст результат с помощью вызова функции в общем цикле (например с помощью twisted.internet.threads.deferToThread).
- Вся работа с внешними и потенциально-тормознутыми данными, это базы данных, сеть и даже работа с файлами, по тем же причинам должна быть разделена на две части (обычно через объект Deferred):
- Первая отправляет запрос
- Вторая (callback) обрабатывает результат когда он появится.
- Вся работа с сетью осуществляется в небезопасном, с точки зрения потоков, режиме. Поэтому для отправки в сеть каких-либо данных из потока необходимо воспользоваться специальными функциями, которые вставят отправку в общий цикл (reactor.callFromThread)
Для Jabber разработчика
Реализация Jabber протокола находится в пакете twisted.words.protocols.jabber.
Пример клиентского приложения
Пример простого бота для Jabber-сервера (источник)
# Эти модули понадобятся. from twisted.words.protocols.jabber import client, jid from twisted.xish import domish, xmlstream from twisted.internet import reactor # Для JID-а используем специальный Twisted-класс me = jid.JID("greutly@swissjabber.ch/TwistedWords") # Так как бот -- это клиентское приложение, то и factory (см глоссарий) # тоже будет клиентским. Библиотека twisted.words.protocols.jabber.client # предоставляет класс для создания factory Jabber-клиентов. factory = client.basicClientFactory(me, "password") # FSM полностью строится на callback-ах. Ждать нельзя. Поэтому писать # что-то вроде "открыть сокет, подождать ответ, послать логин/пароль, # подождать и т.д." тоже нельзя. Для того, чтобы выполнить какие-то # определенные действия после авторизации, наеобходимо создать callback: def authd(xmlstream): # создание XML элемента presence. presence = domish.Element(('jabber:client', 'presence')) presence.addElement('status').addContent('Online') # отправка в xmlstream. Обратите внимание, что это безопасная отправка, # так как эта функция вызывалась из главного цикла и в данный момент мы # единственные, кто сейчас работает с потоком. Остальные, если есть, ждут. xmlstream.send(presence) # Установка обработчика на входящие XML-элементы message. Первый # параметр -- это XPath xmlstream.addObserver('/message', gotMessage) # сам обработчик. параметр message -- XML-элемент # основная функция обработчика -- печатать то, что # пришло. def gotMessage(message): # sorry for the __str__(), makes unicode happy print u"from: %s" % message["from"] for e in message.elements(): if e.name == "body": print unicode(e.__str__()) break # Теперь регистрация callback-а authd. factory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, authd) # И последнее: # Создание главного реактора для клиентского TCP соединения reactor.connectTCP("swissjabber.ch", 5222, factory) # Запуск реактора reactor.run()