Difference between revisions of "Twisted"
(еще немного описание) |
(→Пример клиентского приложения) |
||
| Line 28: | Line 28: | ||
=== Пример клиентского приложения === | === Пример клиентского приложения === | ||
| − | + | Пример простого бота для Jabber-сервера ([http://yoan.dosimple.ch/blog/2007/01/30/ источник]) | |
| + | |||
| + | # Эти модули понадобятся. | ||
| + | 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() | ||
== Ссылки == | == Ссылки == | ||
Revision as of 12:37, 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()