05 января 2016

Подборка полезных XEP расширений протокола XMPP


Пишете свой мессенджер?
Посмотрите на эти расширения, это консолидированный опыт реальных разработчиков.

Внимание: Следует понимать что XEP-ы пилятся сообществом и часто недостаточно согласованно, то есть, не учитывая друг друга, что не хорошо. Конечно, XMPP Council должен отвечать за такие проблемы, но, как можно видеть, фактически никто ни за что не отвечает.


XEP-0013
Flexible Offline Message Retrieval
Это решение вопроса о том что должно быть сделано с сообщениями,
отправленными пользователю который не в сети (offline).


XEP-0045
Multi-User Chat
Описывает процесс превращения приватного диалога в конференцию с сохранением контекста.
Есть механизм приглашений.

Негативный опыт с этим расширением.
В первую очередь, это не групповые чаты, это имитация IRC. Всё. На этом можно было бы закончить про 0045.
Но давайте все-таки разберемся, кто виноват и что делать?

Знаете, как войти в комнату? Послать запрос, чтобы войти в комнату.
Знаете, как создать комнату? Послать запрос, чтобы войти в комнату.
Если её не существует, она создастся. Уникальность имени комнаты сервера решают, кто как хочет. Нравится? Велком ту хелл.

Тот, кто создавал комнату (ну или кто имеет право), задает количество последних сообщений, которые будут отправлены клиенту, который войдет в комнату. Только вошел, а тебе N сообщений с группы прилетело прямо в морду. Самое ужасное, что 0045 не предусматривает хранения оффлайн участников. А пользователь считается вышедшим из комнаты, как только закроет свой клиент. Для того чтоб вернуться потом в эту комнату, вам нужно или запомнить её имя, или воспользоваться XEP-0048. Представьте себе теперь ситуацию: вас пригласили в групповой чат, вы вошли, поговорили и добавили себе эту комнату в букмарки, да еще и указали, чтоб входить в эту комнату каждый раз при логине автоматически. Знаете, что будет, если эту комнату удалили, пока вы были оффлайн? При логине вы прочитаете букмарки и сделаете «вход в комнату», а как мы знаем, что создание не отличается от подключения, то правильно! Вы создадите новую комнату. Еще? У меня для вас будет. Если комнату не указать как «persistent», она будет удалена, как только последний пользователь закроет клиент или выйдет из нее. Вот такие дела, кто виноват — ясно, теперь вопрос: что делать?

Решили мы данную проблему так: все комнаты создаются и конфигурируются, как «member-only», и persistent. В нашем клиенте мы отрисовываем в списке участников всех тех, у кого есть право входить в комнату. Как оказалось, Prosody запрещает получать такой список всем участникам по умолчанию, хотя ХЕР говорит об обратном. Обсудили это с разработчиками Prosody, надеюсь, что договорятся и испрявят. Ну а пока у нас собственное изменение в коде Prosody. Также пришлось сделать изменение, чтобы пользователь мог сам себя исключить из этого списка (да, по умолчанию тоже нельзя), что означает его выход из комнаты. Еще написали кастомный модуль для Prosody, следящий за изменением списка пользователей комнаты (room affiliation) и сообщающий об этом всем участникам. Таким нехитрым способом у нас получились конференции «почти как в скайпе». Интересно, что в XMPP сообществе сейчас обсуждается подобная реализация MUC только используя Pub/Sub, что подтвердил мне один из участников рабочей группы.


XEP-0047
In-Band Bytestreams
Слать большие объёмы данных по нему — идея плохая


XEP-0048
Bookmarks
Расширение позволяющее запомнить имя чат-комнаты в которой ты уже был, но вышел.


XEP-0059
Result Set Management
В нем описаны параметры для получения архива сообщений, упомянута семантика <start>, и <index>, и так далее.


XEP-0065
SOCKS5 Bytestreams
Используется для передачи файлов если обе стороны сидят за Firewall или NAT. Тут при неверной конфигурации или стараниями Firewall регулярно возникают проблемы с соединением.


XEP-0066
Out of Band Data
Позволяет прислать пользователю сообщение, к которому прикреплена музыка/кино/фотка/что-угодно.
Дальше клиент своими средствами это проигрывает/показывает в чатике.


XEP-0085
Chat State Notifications
Полезная штука, всегда хорошо знать, печатает ли пользователь или нет, просто приятный ХЕР.


XEP-0115
Entity Capabilities
Это, конечно, большой плюс. Эта штука позволяет нам узнать, какие из XEP-ов реализованы в клиенте нашего собеседника,
слать ли ему чат стейт нотификейшнс или нет, ну или еще чего там. строка2


XEP-0136
Message Archiving
Для получения архива сообщений вы можете установить только два параметра единичной выборки:
max - который выставит максимальное количество сообщений,
start - который означает время, начиная с которого извлекать сообщения.
При этом надо указать имя определённого пользователя для которого делаем выборку сообщений.

То есть заранее нужно знать с каким пользователем сообщения вытаскивать. А чтобы узнать с какими пользователями вообще было общение
вам нужно вытащить коллекции (термин самого XMPP, означает диалог с каждым отдельным пользователем, в каждый отдельный день) и как-то из них вычленить уникальных пользователей.
Ну или вытягивать из отдельных коллекций.

Выборка по max/start отличается от привычной многим выборке по-странично с выставлением offset и limit.
С другой стороны у механизма с offset и limit тоже есть свои проблемы.
Например в мире SQL, offset и limit — это как бы моветон. Подробности.
Парочка offset/limit в используемой нами MongoDB с точки зрения производительности работает ужасно и везде где можно следует использовать max/start.
Если хотите горизонтально расти до миллионов пользователей в онлайне (ну скажем как World of Tanks),
то для производительности start/max лучше. Смотри XEP-0059.

Через 0136 (или XEP-0313, который сильно упрощает жизнь) можно синхронизировать историю.
Есть индивидуальные настройки архивирования для сессий.
Есть описание что делать в случае если один из пользователей хочет чтобы его сообщения не сохранялись на сервере,
а второй хочет этого.

Пытался найти связку из сервера с поддержкой 0136, клиента для Android и клиента для Windows, чтобы синхронизировалась история. Найти не удалось.


XEP-0154
User Profile
Альтернатива для распространённой технологии vCard, стоит взглянуть.
Однако стандарт так и не был доработан.


XEP-0163
Personal Eventing Protocol
Позволяет клиенту отправлять уведомления всем остальным при изменении своего статуса.
Например можно использовать для аватарок.


XEP-0184
Message Delivery Receipts
Данный черновой стандарт это попытка решения важной проблемы XMPP:
нестабильная работа в нестабильной сети — если соединение рвётся,
сообщения могут теряться, как входящие, так и исходящие.

XMPP работает исключительно по TCP и полагается на стабильность соединения,
нет возможности создавать сессии, размазанные по нескольким соединениям,
нет гарантированной доставки сообщений.

Этот стандарт в паре с XEP-0198 позволяет дать пользователю знать,
что сообщение отправлено и что сервер его получил, и позволяет знать, что сообщение доставлено до адресата.
Очень полезно, но, к сожалению, эта информация не попадает в историю переписки реализованную по XEP-0313.

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


XEP-0191
Blocking Command
Позволяет блокировать спаммеров или отдельные контакты при этом не удаляя их из своего списка собеседников.


XEP-0198
Stream Management
Позволяет преодолевать небольшие сетевые сбои или изменения в низлежащем TCP соединении.
Например, на каждую отправку в сторону сервера он будет отвечать, что он это получил,
таким образом, вы знаете точно, что сообщение было отправлено.
Также позволяет пользоваться протоколом при не стабильном подключении к сети. Например, если вы сидите с телефона и у вас иногда пропадает сеть, то 0198 позволит вам возобновлять подключение, а не делать ре-логин.
Это расширение точно из необходимых.


XEP-0237
Roster Versioning
Хоть и заброшенный, но полезен для экономии полосы пропускания при плохих мобильных соединениях.


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


XEP-0307
Unique Room Names for Multi-User Chat
Позволяет сгенерировать уникальное имя конференции.
К сожалению, статус стандарта «отложен до лучших времен» из-за отсутствия реализаций.
В реальной жизни вполне обходится генерацией уникального UUID.


XEP-0308
Last Message Correction
Это просто очень удобно, поправить очепятку в сообщении, которое уже отправлено.
Это классно, все пользуются, всем теперь легче, грамарнаци спокойны.


XEP-0313
Message Archive Management
Сильно упрощает жизнь если надо синхронизация истории с сервером.
Служит для хранения истории и ее получения.
Пока реализован только в одном сервере и ни в одном клиенте.

Грустное:

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


XEP-0352
Client State Indication
Позволяет клиенту уведомить сервер про то находится ли приложение перед глазами пользователя (foreground). Также позволяет экономить траффик непередавая некоторые пакеты.


XEP-0363
HTTP File Upload
Позволяет ввести обмен файлами в чат-группах и когда ваши собеседники оффлайн.





Автор

© Dmytro Nikandrov