Веб-разработка

индекс
236,88

Как сайт может отправлять события…

Давным-давно (я уже не помню когда, но давно) я собрался и запустил для себя сайт. Сначала он использовался просто как склад того, что нужно кому-то передать. Потом совершенно случайно образовалось свободное время и получилось заполнить сайт чем-то осмысленным и (надеюсь) полезным. И очень захотелось быть в курсе событий, происходящих на сайте. Самое простое решение — отсылать письма, что и было сделано. Однако через некоторое время появилось желание избавиться от писем с сайта так как поток служебной почты в течении дня превышает разумные пределы.

И тут пришла в голову мысль, что использование почты как транспорта для доставки событий сайта является просто одним из распространенных подходов, однако есть еще транспорты, который позволяют не только практически мгновенно передавать сообщения, но еще отслеживать состояние получателя и гарантировать доставку события. Одним из таких транспортов является jabber.

Немного рассуждений перед тем, как бросаться в реализацию.


Итак, на данный момент сервер мне отсылал письма, в любое время:
  1. Предложения/замечания, которые можно отправить с сайта
  2. Информацию о скачивании файлов с сайта
  3. Регулярно небольшую статистику

Не все из этих событий мне нужно было доставлять в любое время: информация о скачивании файлов с сайта мне нужна как факт того, что «вот прям сейчас кто-то берет файл с сайта», а не выгребать утром несколько писем после получения почты. Статистику вообще было бы интереснее получать по запросу (да, можно просто сделать страницу, однако такие страницы обычно превращаются в монстриков, а нужно видеть нечто типа summary). Таким образом отправка событий должна получиться такой:
  1. Предложения/замечания, которые можно отправить с сайтаотправляется всегда
  2. Информацию о скачивании файлов с сайта -отправляется только тогда, когда я в режиме on-line
  3. Регулярно небольшую статистикутогда, когда мне захотелось на нее взглянуть

Кстати, IM клиент у меня запускается автоматом и намного раньше, чем почтовый клиент т.е. события сайта я увижу быстрее.

Подготовительная работа.


Для начала я завел jabber ID, под которым будет работать мой сайт. Я не стал возиться с поддержкой сайтом запросов авторизации, все необходимые действия по добавлению контактов и авторизации я проделал вручную т.к. это всего лишь эксперимент. В дальнейшем нужно привязать зарегистрированных пользователей к контакт-листу сервера.
Вторым по важности делом был выбор библиотеки для работы с jabber протоколом. В сети нашлось достаточное количество проектов для .NET, но окончательный выбор какой-то конкретной библиотеки я еще не сделал т.к. еще продолжаю их сравнение.

Делаем из сайта jabber клиента.


Все готово к реализации и первый код, который был написан, всего лишь выполнял вход на jabber сервер и появлялся у меня в online контактах при старте сайта. Первая проблема, которая грозила остановить эксперимент: некоторые библиотеки почему-то считают, что они просто обязаны спрашивать подтверждения у пользователя. Естественно, что сайт им ничего ответить не мог, да и простого окна создавать не давал. После простой замены библиотеки для работы с протоколом я наконец-то увидел долгожданную надпись "[Server] On-Line" Тут я погорячился — эта проблема встретилась мне совершенно в другой библиотеке — библиотеке для работы с SVN, которую я тоже пристраивал к сайту.

Начинаем слать события.


Собственно вся разработка заключалась в написании метода void SendMessage(Jid to, bool alwayssend, string format, params object[] args) и расстановкой вызовов этого метода. Так же написал небольшой метод для автоответа:
  1.     protected void processMessage(Jid jid, string text)
  2.     {
  3.       string cmd      = new Regex("\\s+", RegexOptions.ECMAScript).Replace(text, " ").ToLower();
  4.       switch (cmd)
  5.       {
  6.         case "?":
  7.           SendMessage(jid, false, "Команды:\n"+
  8.                       "как дела? - текущая статистика\n"+
  9.                       "посетители? - список IP посетителей\n"+
  10.                       "страницы? - список страниц\n"+
  11.                       "откуда приходили? - список ссылающихся серверов.");
  12.           break;
  13.         case "как дела?":
  14.           SendMessage(jid, false, Collector.GetSummary());
  15.           break;
  16.         case "посетители?":
  17.           SendMessage(jid, false, Collector.GetIPs());
  18.           break;
  19.         case "страницы?":
  20.           SendMessage(jid, false, Collector.GetPages());
  21.           break;
  22.         case "откуда приходили?":
  23.           SendMessage(jid, false, Collector.GetServers());
  24.           break;
  25.       }
  26.     }
* This source code was highlighted with Source Code Highlighter.

Все, теперь я вижу, когда мой сайт работает, посылает мне нужные события и отвечает на вопросы. Вот так выглядит окно чата с моим сайтом:
image
Собственно написать автоответчик не составляет труда.

Итоги.


Использовать протокол jabber как транспорт для доставки событий сайта удобно и несложно. Сразу видно преимущество — все события можно разделить на несколько типов и привязать к наличию пользователя (в данном случае меня) на связи и (если нужно) к моему статусу (не беспокоить, занят и т.п.):
  • Важные сообщения — то, что я обязательно должен увидеть
  • События, которые представляют интерес, но когда я в off-line или мой статус говорит о моей загруженности, то их можно и не отсылать
  • Информация, отсылаемая по запросу — только тогда, когда я захотел на нее посмотреть, т.е. это вообще выглядит как командная строка :)

Сократилось число «как бы» нужных писем, которые в 99% случаев удаляются без прочтения.
Вообще оказалось, что потенциал такого решения достаточно высок. Например можно пойти дальше — кардинально изменить процесс регистрации: спрашивать только jabber ID, посылать запрос авторизации, вытаскивать начальные данные и отсылать пароль, но пока останавливает низкая распространенность использования протокола.
Реализация тестового механизма на сервере уместилась в 134 строк кода, если кому интересно — могу выложить, но этот код практически полностью взят из примеров, которые шли с библиотекой. Пока мне результаты нравятся, эксперимент продолжается. Впереди — тестирование нагрузки, плотная работа со списком контактов через сайт и еще куча идей.

Дополнение: о компонентах для работы с jabber

Первый достойный проект — Jabber .NET: так как почта и jabber для моего домена работает через Google Apps, то главный критерий — нормальная работа именно с google, подключение работа прошли без проблем. Есть некоторые недоработки, но основные функции обеспечиваются достаточно хорошо. Что меня не устроило:
  1. Наследование объектов от System.ComponentModel.Component
  2. Несколько DLL
  3. Структура проекта мне совершенно непонятна, слишком перемешаны проекты


Второй проект — agsxmpp: на данный момент использую его, но скорее всего придется отказаться из-за лицензии. Опять же с google работает нормально, библиотека посерьезней, чем первая.

Обе рассмотренные библиотеки содержат компоненты для Windows.Forms, но во-первых на них без содрагания смотреть нельзя, а во-вторых они мне на сервере ненужны.

Все остальное, что я смог найти отметалось уже на этапе изучения сайтов. Однако есть неплохие JScript проекты, может какой-нибудь из них просто-напросто портировать на C#.
+87
3 ноября 2008, 05:32
89

комментарии (43)

+8
AntonPavlov #
хорошее решение
+1
PingWin #
собсно, имхо логичным дополнением к статье был бы небольшой обзор/впечатления от опробованных библиотек… а то написано например, что одна из либ не преспособлена для работы под сервисом, а какая — не указано…
+7
Devgru #
Ещё надо добавить
case "где я?":
+2
ETCDema #
Лучше
case "ты кто?":


Дабы не забыть, что за контакт такой в списке из 200 человек.
0
ernt #
А Вы у всех забытых контактов так прямо и спрашиваете? :)
+5
NecroHill #
классикой было бы
case «кто здесь?»: )))
+2
Treg #
элегантное решение, запости в веб-разработку!
0
ETCDema #
Перенес.
НЛО прилетело и опубликовало эту надпись здесь
–1
ETCDema #
Это все-таки не лог, это сообщения о событиях на сайте. Перенаправлять лог из файла в jabber несколько неразумно :).
+3
sunnybear #
да, роботы уже среди нас…
–2
phpdude #
а почему не в icq? либы не нашлось? :-D
+6
Holy_Cheater #
Если бы вы знали как надо насиловать собственный мозг, чтобы сделать нормальную рабочую icq-либу, а потом еще постоянно глядеть чего же там AOL опять на серверах изменили, и делать так чтоб всё работало — вы б отказались от затеи.
XMPP гораздо проще кодится.

По теме: Хорошая задумка. При желании можно подобный сервис реализовать через Jabber Component Protocol (XEP-0114), правда тогда придётся еще и сервер ставить. Но там можно реализовать плюшки типа форм и ad-hoc команд.
Но в общем-то командная консоль через чат — очень даже удобно :)
0
phpdude #
вы правы. а насчет icq, это да. я писал свою либо, сделал получить отправить принимать сообщения и еще какие то плюшки, ну логин конечно. остановился, встал на ютф -8 :(
неправильно чтото работало, потом отвлекся и забыл про это)
0
Holy_Cheater #
там частично utf-8 поддерживается в channel2. Это если друг другу сообщения отправлять, при условии что оба контакта друг другу видны. А pidgin (и может adium) не поддерживают вообще это дело. Кроме как насильно юзать нужную кодировку для channel-1 сообщений и userdetails, ничего не сделаешь.

Ну и плюс с документацией проблемы, протокол-то закрытый. И структуры данных там заставляют шевелиться волосы на голове.
0
phpdude #
я переписывал webicqpro (php версия), сделал на 90% где то кажется, в ютф была загвостка если я вас не обманываю)

а протокол да, хер найдешь норм документацию, есть дампы байт, но нахрен они нужны, если к ним даже не написано откуда они и куда слать их) обрывки мыслей другими словами.
+2
ETCDema #
Как бы даже и не искалась. ICQ протокол для меня неактуален.
0
adeptus #
«Статистику вообще было бы интереснее получать по запросу (да, можно просто сделать страницу, однако такие страницы обычно превращаются в монстриков, а нужно видеть нечто типа summary)»
А есть ли какие-то решения для создания подобных страничек-монстриков?
0
ETCDema #
Специальных библиотек я не знаю, но в рабочих проектах у меня собирается достаточно объемная статистика: времена выполнения страниц, отдельных запросов и количество их вызывов, состояние кэша, динамика сессий, состояние объектов уровня приложения и т.п. Сбор всей этой инфы достаточно тесно завязан с самим приложением. Собственно на странице вывода иногда получаются таблички более 1000 строк.
0
adeptus #
Я имел в виду странички с информацией о состоянии сторонних сайтов, не самописных. Например, данные счетчиков посещений а нужном формате и собранные на одном монстрике.
0
ETCDema #
Нет, такого не делал.
0
gtbear #
Делал подобное у себя на сайте. Но я использовал webicqpro и писал на пхп. Когда необходимо отослать сообщение скрипт с сайта шлет IPC сообщение боту, который все время запущен. При получении сообщения от пользователя это сообщение то же через IPC выкидывается специальному демону который обрабатывает запросы. Получилось очень даже удобно. Если кому нить интересно можно написать мануальчик чего как делать.
0
0xBA0BAB #
Кстати да, а под пхп подобные либы встречаются?
0
hannimed #
ru2.php.net/manual/ru/book.dotnet.php — Если, конечно php работает под виндой ;)
0
0xBA0BAB #
Работает. Но суть не в этом. Так неинтересно. Jabber — открытый протокол, а потому ожидается, что будет много библиотек — хороших и разных.
+1
ETCDema #
Когда искал, натыкался вот на такую: code.google.com/p/xmpphp/
+2
tapin13 #
тоже на нее наткнулся, вечером буду проводить эксперименты :)
Автору спасибо за статью.

Перешел на qip и jabber, много плюсов, но главный для меня это SSL :]
0
pleax #
согласен, неплохое решение.
я недавно буквально обдумывал реализацию подобного функционала. в итоге сделал на rss.
теперь подумаю, чтобы xmpp внедрить дополнительно.
0
ETCDema #
Использование rss по сути ничем от страницы не отличается и всевозможные rss ридеры опрашивают страницы на предмет изменений. Если использовать jabber, то событие придет без всякого дополнительного опроса и ровно в тот момент, когда это событие будет создано -> меньше нагрузка на сервер.
–6
DIDJER #
А почему не воспользоваться ICQ-протоколом?
+3
ETCDema #
Закрытый:
1. Нужно или писать свою библиотеку (время жалко) или искать что-то вменяемое уже написанное
2. Есть шанс нарваться на очередную смену протокола
3. Сайт будет получать спам

0
niksite #
> и гарантировать доставку события

Увы, но XMPP не умеет квитирования сообщений, отчего доставка всё же не гарантирована, хотя и весьма вероятна.
0
ETCDema #
Скажем так, вероятность доставки выше, чем у почты.
0
ivankin #
А сделать несколько RSS потоков и скормить RSS-аггрегатору?
0
ETCDema #
Как я писал выше, использование rss по сути ничем от страницы не отличается и всевозможные rss ридеры опрашивают страницы на предмет изменений. Если использовать jabber, то событие придет без всякого дополнительного опроса и ровно в тот момент, когда это событие будет создано -> меньше нагрузка на сервер.
+1
ugnich #
А вот так можно отправлять сообщения на jabber с помощью Perl:
blog.ugnich.com/2008/08/22/notifications_via_jabber_xmpp/
0
xintrea #
Скажыте, а чем это лучше входа в админку и кликанья по ссылкам

«как дела»
«посетители»
«страницы»
«откуда приходили»

?
0
ETCDema #
Это просто пример, однако для получения этих данных ненужно запускать браузер, заходить на сайт и авторизоваться.
0
xintrea #
Но зато нужно запускать jabber-клиент, находить контакт и писать команды.
0
ETCDema #
Не спорю, что нужно, однако как минимум клиент у меня запущен всегда. Самая главная идея здесь — не управлять сайтом, а оперативно получать от него сообщения о каких-либо событиях. Использование команд тут — как бесплатное приложение.
–1
egorinsk #
Идея интересная, в некоторых случаях полезная. Но мне кажется, хорошая админка могла бы быть удобней.

Хотите еще идею бесплатно? Заводим по контакту на каждый сайт, и делаем так. что пока сайт работает — контакт в Сети, упал — в офлайне (а в Х-статус пишем статистику посещений). Одним взглядом видим состояние всех наших сайтов)))
0
ETCDema #
Конечно это не замена админки, а дополнение к ней.
У меня как раз при старте сайта он появляется в он-лайне, при выгрузке соответственно отключается (это как раз один из бонусов использования IM вместо почты).
Насчет количества хитов и сессий в статусе — это тема, но я у себя статусы не вывожу т.к. народ такую пургу иногда туда пишет…
–1
wilwill #
вот было бы клева увидеть такой скрипт как плагин для wordpress

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.