У нас было социальное приложение без чата, 2 недели на его разработку и абсолютно никаких знаний о существующих протоколах для реализации IM. Не то что бы это был необходимый набор для того чтобы выстрелить себе в ногу, но в процессе работы это произошло. Несколько раз.
— Паша, нам нужно сделать чат.
— Да всё просто, у меня тут знакомые использовали XMPP для чата в своём приложении.
Какие у нас были требования? Да ничего особенного, простой обмен сообщениями между пользователями, без групповых разговоров. Платформы: веб (с поддержкой работы через вебсокеты), Android, iOS. Создание пользователей должно автоматически производится только нашим серверным приложением. Конечно неплохо было бы иметь отметки о том прочитано сообщение или нет(предполагается, что приложение может быть использовано с разных девайсов), и иметь возможность просмотреть лог чата. В общем стандартный функционал для мгновенного обмена сообщениями в 2015 году. Бонусные баллы начисляются если сервер умеет горизонтально масштабироваться.
Хм, звучит заманчиво. Гуглим сравнение с другими стандартами, открываем ссылку на статью в википедии. Первая мысль: ого, круто, тут есть всё что нам нужно.
Почему же мы выбрали именно XMPP?
Ребята разрабатывавшие протокол действительно многое предусмотрели. Например, взглянем на дизайн архивирования сообщений. Индивидуальные настройки архивирования для сессий. Описание что делать в случае если один из пользователей хочет чтобы его сообщения не сохранялись на сервере, а второй хочет этого. При этом нормального механизма получения архива сообщений по страницам нет. Под нормальным я подразумеваю выставление offset и limit. Здесь вы можете установить только параметр max, который выставит максимальное количество сообщений и параметр start, который означает время, начиная с которого вы будете получать сообщения.
Или вот например: протокол не определяет что должно быть сделано с offline сообщениями (сообщения, посланные пользователю не в сети). Поэтому большинство серверов просто вышлют их пользователю при следующем логине. Помните требование про то, что пользователь может пользоваться приложением с нескольких устройств? Так вот, если вы запустите приложение на смартфоне, а потом войдёте в веб-приложение, то все offline сообщения придут на ваш смартфон и… всё. То есть в веб-приложении вы об этом никак не сможете узнать. Стоит отметить что некоторые сервера ведут себя по-другому, то есть реализуют XEP-0013.
Ах да, протокол для IM (instant messaging) в 2015 году не имеет спецификации, которая позволяла бы получить список непрочитанных сообщений и отметить прочитанными какие-то из них. Совсем.
В самом начале я ещё не знал с какими проблемами из предыдущего пункта мне придётся столкнуться и поэтому в качестве реализации сервера был выбран MongooseIM. Масштабируемый, умеет запрещать разрешать регистрацию только с определённых ip, поддерживает вебсокеты. Для веб front-end была выбрана библиотека JSJaC, потому что по сравнению с strophe.js предоставлял более удобное API. Простая страничка из примеров JSJaC подключилась к серверу с пол-пинка и радости моей не было предела. Казалось бы, работа закончена. Ну почти.
И вот тогда я столкнулся с последней озвученной проблемой из предыдущего пункта. Поскольку протокол не подразумевает возможность получить непрочитанные сообщения, да и вообще не говорит о прочитанности/непрочитанности сообщений, эту часть функционала придётся дописывать самому. Будучи не сильным в программировании на erlang-е я принялся искать другие подходящие реализации сервера. Искал я реализации на Java или JavaScript.
Openfire — одна из самых популярных реализаций XMPP на Java. К плюсам можно отнести простоту настройки: всё происходит через веб-интерфейс. Дальше только минусы: требовательность к ресурсам, отсутствие плагина для работы через вебсокеты.
Единственным достойным упоминания из проектов на JavaScript оказался xmpp-ftw. Проект реализует много расширений из XMPP. Однако от его использования пришлось отказаться, поскольку мы бы не смогли использовать существующие клиентские библиотеки. Возможно всё было бы не так хорошо и с ним.
Tigase поначалу казался спасением. Быстрый, масштабируемый сервер на Java, с возможностью написать плагин и довольно просто его подключить. И отсутствием документации. Вместо неё рекомендовалось читать исходный код. Но это ничего, я и так чаще всего так и делаю. Я написал плагин, который помечал новые сообщения непрочитанными. Чтобы регистрировать пользователей пришлось напрямую писать их в базу, поскольку API для администрирования так и не удалось нормально использовать. К счастью Tigase имеет драйвер для подключения к Mongodb. Получение непрочитанных сообщений сделано отдельным методом API приложения(костыль, можно было сделать и плагином внутри Tigase, но отняло бы намного больше времени, потому что для общения с СУБД внутри Tigase используется довольно низкоуровневое API). Подключив всё я проверил — пока сообщение не помечено прочитанным (кстати, сообщения не имеют id в xmpp, поэтому помечать было решено прочитанной всю переписку с конкретным пользователем) оно возвращается в списке непрочитанных. Всё работает. Осталось проверить только случай с offline сообщением. Да, оно не помечалось непрочитанным, потому что плагин который обрабатывает offline сообщения срабатывает раньше, чем архивирование. На форуме Tigase разработчик ответил что нужное мне поведение реализовано в коммерческом проекте Tigase Unified Archive. Гугление по его названию ни к чему не привело, разработчик на форуме сказал что проект пока нестабилен и нет релизной версии. Покопавшись в исходниках сервера нашёл что можно получить нужное поведение выставив всем сообщениям тип chat.
Теперь пройдёмся по реализациям клиентов. Начнём с JavaScript реализаций. Пробовали мы только JSJaC, который в итоге поменяли на strophe.js. Первый имеет более приятное API, но он имеет только базовую функциональность, не поддерживая работу с расширениями, например с архивом. В то же время strophe вместо этого предлагает довольно удобный xml-билдер. Ну что ж, абстрагироваться от внутренностей XMPP не получилось. Кстати, вебсокет-коннектор в JSJaC работает только в Webkit.
Из Java клиентов попробован на данный момент только Smack. В случае посылки некорректного пакета скорее всего будет выброшен NoResponseException, и это всё что вы узнаете.
Может быть, моя проблема в том, что я надеялся что кто-то решил часть моих проблем за меня и сделал это хорошо. Знай я всё это сначала — предложил бы написать собственный чат-сервер. Серьёзно. Дело не в том что протокол плох или не подходит для использования для реализации IM с современными требованиями, хотя я до сих пор так считаю. Просто я бы предпочёл иметь свой собственный код и заложить нужные возможности для расширения, чем перелопачивать столько чужого кода и спецификаций. XMPP вполне успешно применяется для решения огромного круга задач, для которых он, надо полагать, хорошо подходит. Хотя большинство решений используют только базовый функционал.
— Паша, нам нужно сделать чат.
— Да всё просто, у меня тут знакомые использовали XMPP для чата в своём приложении.
Какие у нас были требования? Да ничего особенного, простой обмен сообщениями между пользователями, без групповых разговоров. Платформы: веб (с поддержкой работы через вебсокеты), Android, iOS. Создание пользователей должно автоматически производится только нашим серверным приложением. Конечно неплохо было бы иметь отметки о том прочитано сообщение или нет(предполагается, что приложение может быть использовано с разных девайсов), и иметь возможность просмотреть лог чата. В общем стандартный функционал для мгновенного обмена сообщениями в 2015 году. Бонусные баллы начисляются если сервер умеет горизонтально масштабироваться.
Хм, звучит заманчиво. Гуглим сравнение с другими стандартами, открываем ссылку на статью в википедии. Первая мысль: ого, круто, тут есть всё что нам нужно.
Почему же мы выбрали именно XMPP?
- XMPP — это открытый протокол, разрабатываемый XSF (XMPP Standards Foundation), независимой некоммерческой организацией. Эти ребята должно быть довольно умны и предусмотрели всё, что нужно протоколу обмена сообщениями (ага, конечно).
- Поскольку протокол открытый должно быть довольно много реализаций сервера, и хотя бы одна из них будет достаточно хороша чтобы её использовать.
- По этой же причине для каждого из языков программирования наверняка найдётся 1-2 библиотеки.
- Первая буква X в аббревиатуре означает extensible, расширяемый. Даже если что-то нам не понравится в протоколе мы всегда сможем расширить своими методами.
Протокол
Ребята разрабатывавшие протокол действительно многое предусмотрели. Например, взглянем на дизайн архивирования сообщений. Индивидуальные настройки архивирования для сессий. Описание что делать в случае если один из пользователей хочет чтобы его сообщения не сохранялись на сервере, а второй хочет этого. При этом нормального механизма получения архива сообщений по страницам нет. Под нормальным я подразумеваю выставление offset и limit. Здесь вы можете установить только параметр max, который выставит максимальное количество сообщений и параметр start, который означает время, начиная с которого вы будете получать сообщения.
Или вот например: протокол не определяет что должно быть сделано с offline сообщениями (сообщения, посланные пользователю не в сети). Поэтому большинство серверов просто вышлют их пользователю при следующем логине. Помните требование про то, что пользователь может пользоваться приложением с нескольких устройств? Так вот, если вы запустите приложение на смартфоне, а потом войдёте в веб-приложение, то все offline сообщения придут на ваш смартфон и… всё. То есть в веб-приложении вы об этом никак не сможете узнать. Стоит отметить что некоторые сервера ведут себя по-другому, то есть реализуют XEP-0013.
Ах да, протокол для IM (instant messaging) в 2015 году не имеет спецификации, которая позволяла бы получить список непрочитанных сообщений и отметить прочитанными какие-то из них. Совсем.
Реализации
В самом начале я ещё не знал с какими проблемами из предыдущего пункта мне придётся столкнуться и поэтому в качестве реализации сервера был выбран MongooseIM. Масштабируемый, умеет запрещать разрешать регистрацию только с определённых ip, поддерживает вебсокеты. Для веб front-end была выбрана библиотека JSJaC, потому что по сравнению с strophe.js предоставлял более удобное API. Простая страничка из примеров JSJaC подключилась к серверу с пол-пинка и радости моей не было предела. Казалось бы, работа закончена. Ну почти.
И вот тогда я столкнулся с последней озвученной проблемой из предыдущего пункта. Поскольку протокол не подразумевает возможность получить непрочитанные сообщения, да и вообще не говорит о прочитанности/непрочитанности сообщений, эту часть функционала придётся дописывать самому. Будучи не сильным в программировании на erlang-е я принялся искать другие подходящие реализации сервера. Искал я реализации на Java или JavaScript.
Openfire — одна из самых популярных реализаций XMPP на Java. К плюсам можно отнести простоту настройки: всё происходит через веб-интерфейс. Дальше только минусы: требовательность к ресурсам, отсутствие плагина для работы через вебсокеты.
Единственным достойным упоминания из проектов на JavaScript оказался xmpp-ftw. Проект реализует много расширений из XMPP. Однако от его использования пришлось отказаться, поскольку мы бы не смогли использовать существующие клиентские библиотеки. Возможно всё было бы не так хорошо и с ним.
Tigase поначалу казался спасением. Быстрый, масштабируемый сервер на Java, с возможностью написать плагин и довольно просто его подключить. И отсутствием документации. Вместо неё рекомендовалось читать исходный код. Но это ничего, я и так чаще всего так и делаю. Я написал плагин, который помечал новые сообщения непрочитанными. Чтобы регистрировать пользователей пришлось напрямую писать их в базу, поскольку API для администрирования так и не удалось нормально использовать. К счастью Tigase имеет драйвер для подключения к Mongodb. Получение непрочитанных сообщений сделано отдельным методом API приложения(костыль, можно было сделать и плагином внутри Tigase, но отняло бы намного больше времени, потому что для общения с СУБД внутри Tigase используется довольно низкоуровневое API). Подключив всё я проверил — пока сообщение не помечено прочитанным (кстати, сообщения не имеют id в xmpp, поэтому помечать было решено прочитанной всю переписку с конкретным пользователем) оно возвращается в списке непрочитанных. Всё работает. Осталось проверить только случай с offline сообщением. Да, оно не помечалось непрочитанным, потому что плагин который обрабатывает offline сообщения срабатывает раньше, чем архивирование. На форуме Tigase разработчик ответил что нужное мне поведение реализовано в коммерческом проекте Tigase Unified Archive. Гугление по его названию ни к чему не привело, разработчик на форуме сказал что проект пока нестабилен и нет релизной версии. Покопавшись в исходниках сервера нашёл что можно получить нужное поведение выставив всем сообщениям тип chat.
Теперь пройдёмся по реализациям клиентов. Начнём с JavaScript реализаций. Пробовали мы только JSJaC, который в итоге поменяли на strophe.js. Первый имеет более приятное API, но он имеет только базовую функциональность, не поддерживая работу с расширениями, например с архивом. В то же время strophe вместо этого предлагает довольно удобный xml-билдер. Ну что ж, абстрагироваться от внутренностей XMPP не получилось. Кстати, вебсокет-коннектор в JSJaC работает только в Webkit.
Из Java клиентов попробован на данный момент только Smack. В случае посылки некорректного пакета скорее всего будет выброшен NoResponseException, и это всё что вы узнаете.
Вывод
Может быть, моя проблема в том, что я надеялся что кто-то решил часть моих проблем за меня и сделал это хорошо. Знай я всё это сначала — предложил бы написать собственный чат-сервер. Серьёзно. Дело не в том что протокол плох или не подходит для использования для реализации IM с современными требованиями, хотя я до сих пор так считаю. Просто я бы предпочёл иметь свой собственный код и заложить нужные возможности для расширения, чем перелопачивать столько чужого кода и спецификаций. XMPP вполне успешно применяется для решения огромного круга задач, для которых он, надо полагать, хорошо подходит. Хотя большинство решений используют только базовый функционал.
rumkin
Вообще парадокс – до сих пор нет какого-то общего стандарта для общения с любых устройств условно неограниченному кругу лиц кроме почты, которая уже морально устарела.
Я для подобных целей изобретал свой велосипед на основе протокола сродни бинарному HTTP/2 с аутентификацией по ed25519.
allter
Почта стандартна только потому, что получила распространение задолго до того, как в интернет забрели корпорации… XMPP — вполне нормальный стандарт. То, что разработчики приложений на его основе закрывают свои сервера и протоколы — это не его проблемы, а особенности финансирования разработчиков приложений…
rumkin
Я не заявляю, что XMPP плох. Скорее говорю об общей картине. Последние несколько лет наблюдается постепенное снижение интереса к XMPP, почта перестала удовлетворять потребностям повседневного общения. Вакуум какой-то.
Doktor_Gradus
Какое снижение интереса? Больше половины новых мессенджеров, полезших в последнее время, как грибы после дождя, написаны с использованием XMPP.
Doomsday_nxt
Откуда статистика?
avsavchenko
Оттуда что берут за основу XMPP вносят в него изменения свои и закрывают исходники, к примеру WhatsApp, mail.ru Agent, etc
Scratch
а еще есть TextSecure от WhisperSystems или просто OTR и не надо ничего изобретать )
rumkin
Мое решение отличается архитектурно и использует pubsub-модель. Сервер отвечающий за хранение сообщений, слушает канал как обычный клиент и записывает сообщения в базу. Как таковой он не является посредником и может быть успешно исключен из процесса общения.
qbtarzan
ну это вы погорячились, есть стандарты и протоколы, используемые в том числе в авиации, у военных, в космосе и т.п., например DDS. Также есть AMQP и подобные, просто они пока еще не так широко известны, но с развитием IoT, думаю, получат бурное развитие
JagaJaga
Почему почта устарела?
Louter
«Морально устарела» это из серии «задолбало этим пользоваться». Синдром желания новинок, который умные маркетологи, обозвали «изменением коньюктуры рынка» и «изменение жизни, потребностей», а пипл подхватил =)
Хотя любопытное дело: нет до сих пор нормального почтовика для дроидов (OpenSource, адекватная поддержка SSL, полная поддержка SMTP и полная, адекватная поддержка IMAP). А человек тут про XMPP жалуется) (почтовики для иОС не смотрел за ненадобностью)
Есть К9, но как оказалось, он считает, что сервер обязательно далжен отвечать алгоритм передачи пароля. Но нет, это не так. Не работает.
Есть АкваМэйл. Всё круто, но адекватной поддержкой IMAP назвать нельзя: море непонятного и «левого траффика»
Остальные либо совсем сырые и с SMTP/IMAP мало дружат или закрытый исходный код)
Возможно что-то упустил, любопытно узнать альтернативы)
Doomsday_nxt
А зачем Вам, как пользователю, open source?
dbanet
Щито? Не ожидал услышать такого на хабре.
bolk
А что тут такого? Бо?льшая часть программ на моём компьютере (включая ОС и BIOS (или что там вместо него сейчас?)) — бинарные. Остальные с открытым кодом, но у меня нет никакого желания в нём копаться. И, да, непонятно — зачем пользователю (а айтишники частенько выступаю в роли пользователя) открытый код?
Скажем, LibreOffice у меня на компе — с открытым кодом. Если у меня баг в отображении вордовского документа, лезу ли я в код? Боже упаси! Читал ли я код хоть раз, чтобы понять — нет ли в нём закладок? Никогда!
Как и 99% читателей Хабра.
dbanet
Простите мне мою леность: спорить с вами не буду.
bolk
Да и этот комментарий не стоило писать.
dbanet
Который комментарий?
Пожалуйста, воздержитесь от указаний о том, что стоит или не стоит делать другим хабралюдям. Не берите на себя слишком многого, и позвольте голосам за комментарии и карму делать их работу.
bolk
А есть сомнения в том какой комментарий? Вот этот бессмысленный комментарий «простите мне мою леность: спорить с вами не буду».
Я высказал своё мнение: писать его не стоило. Вы же как раз мне указываете что делать и что не делать, причём достаточно однозначно: воздержитесь от указаний… не берите на себя слишком многого, и позвольте….
dbanet
Вместо написания комментария о том, стоило ли писать какой-либо комментарий, просто нажмите соответствующую стрелочку. Она нужна именно для этого.
Не создавайте информационный шум: не всем интересно ваше мнение по поводу чужих комментариев.
В своём комментарии, который вас так задел, я всего лишь искренне извинился перед вами, что не буду отвечать на ваши вопросы и поддерживать с вами диалог на эту тему, дабы вы ненароком не сочли бы это моим неуважением к вам. Вежливость и участие.
Больше так не буду.
bolk
Опять вы мне указываете что делать: жмите на стрелочку, не пишите комментарии?
Borz
но это же известное «никогда не говори никогда» только в форме «не указывайте мне что мне делать»
Louter
А такого, что на этот вопрос уже было отвечено-переотвеченно тьму тёмную количество раз, чем опен-соурс так качественно приемлее для конечных же пользователей, нежели проприетарные программы.
Риторика...И если бы Вы жили в Германии было бы очень интересно, на сколько Вас интересует работа ПО на компе и гаджетах с учётом того, что вся отвестенность на Вас и никого не… волнует, что Вы не знали, что ПО может быть ретранслятором и через гаджет (тот же почтовик) прошло террористическое письмецо. А так, выходя из крайностей, то открытый код качественно лучше развивается. Не зря даже такие мастадонты, как мелкомягкий хотят часть продуктов (а часть уже) перевести на открытый исходный код.
Вот смотрю на людей и диву даюсь: держать почту на гугле, допустим, т.е. у врага, и это норм. Использовать почтовые клиенты и не думать, что это сильно влияет на нашу с вами жизнь, на ценообразование.
VolCh
Зато 1% (по вашим оценкам) таки читают, исправляют или хотя бы информируют сообщество. А 99% могут проверить их слова о, например, уязвимостях.
bolk
См. многочисленные истории про OpenSSL. То, что эту библиотеку смотрела куча глаз, не уберегло её от ряда серьёзных уязвимостей.
vlivyur
А будь она закрытым проектом, то уязвимости до сих пор бы жили в нём.
bolk
У вас прям какая-то вера религиозной природы.
Давайте простой пример. «Циски», которые стоят почти повсеместно — дырявое решето?
Крупные компании тратят на экспертизу своих проектов приличные деньги и этот процесс носит постоянных характер, тогда как у проектов с открытым кодом это всё неорганизованно, стихийно.
Конечно, бывают исключения.
vlivyur
А что, cisco не устраняет свои ошибки и не выпускает обновления? Может и не решето, но дырки точно есть.
Гарантий нет ни в том, ни в другом случае. И уже надоело видеть «все смотрели, но за двадцать лет так и не обнаружили». Обнаружили? Да. Исправили? Да. Быстро? Ну уж явно не медленнее корпораций. И если с OSS приобретаешь просто геморрой, то с корпорациями всё то же самое, но за деньги.
bolk
Устраняет. Видите, я к тому и веду — открытый код (как и закрытый) ничего не гарантирует. Пусть будет и то и другое, нет смысла фанатично примыкать к какому-то лагерю.
Louter
За тем же, зачем и SSL, OpenGPG, чтобы иметь возможность убедиться или разубедиться в том, что почтовик не сливает данные в какую нить агитационно-националистическую базу. Или ещё хуже — торгашам. Чтобы после почтового сообщения «тем эти лекарства дешёвые» (замените слово «лекарства» любым) вдруг не подпрыгивали цены в том месте или вдруг не исчезала торговая точка.
Опять в карму нагадили ироды окоянные. Посмотрите для начала фильм 99 франков =)
rumkin
Устарела как формат повсеместного повседневного общения. Она была разработана, когда Интернет был «по карточкам», использовался чаще в профессиональных целях и было удобнее написать одно длинное письмо и через пару дней ждать ответа. Сегодня же отсутствие пользователя онлайн скорее исключение нежели правило. У пользователей ярко выразились новые роли. Почта стала выполнять новые функции, например такие как аутентификация. Но подстроилась ли почта под новые требования? Сколько дополнительных программ приходится использовать для общения пользователю? Для личного общения WhatsApp, для деловой переписки – Skype, для разработки – Slack. Электронная почта стала одной из. Она продолжает пользоваться популярность исключительно из-за распространенности и своего привилегированного положения – только у почты есть унифицированная система адресации имя@хост.
bogolt
Почта это единый протокол обмена сообщениями. В отличие от ватсаппов, фейсбуков и другой шелухи которая сегодня есть, а завтра ее уже не станет. Или станет но внутри флеш плеера, только на виндовс 10 в браузере ИЕ.
Почта одна из очень немногих дает вам возможность быть независимым, быть хозяином своей информации.
rumkin
Вы приводите плюсы почты, которые я никак не умаляю. А я говорю о том, что технически на основе почтового протокола трудно сделать что-то новое, и включить почтовый протокол в имеющийся сегодня проект никому и в голову не придет. Например, если я захочу сделать ресурс, пользователи которого смогли бы писать сообщения пользователям другого ресурса, то мне будет проще написать web api для получения данных от другого ресурса по HTTP протоколу, чем создавать параллельную инфраструктуру для работы с почтовым протоколом и внедрять это в свой проект. Почта реализует собственный транспортный протокол и при этом имеет не самую лучшую поддержку коммуникационных функций. Было бы вполне логичным в эпоху глобального HTTP, отказаться от собственного транспорта и сконцентрироваться на развитии коммуникационной составляющей.
Электронная почта устарела как технология, просто достойной альтернативы нет. За подтверждением далеко ходить не надо – вы, будучи хозяином своей информации, держите почту в gmail, где вы всего лишь гость.
bogolt
Да разумеется все так. Она устарела, она не очень удобная, просто адекватной замены пока не выросло.
JagaJaga
Я бы не хотел работать с людьми, для которых преимущественно общение через Skype или какой-то Slack.
Почта универсальна, подходит под любые нужны. А ваши все форматы могут исчезнуть в любой момент. Почта тоже, но это менее вероятно.
Для личного общения почта устарела, это факт. Сейчас этим балом правят всякие мессенджеры.
Но для делового общения и для работы лучше (ИМХО) и универсальней почты пока что ничего нет.
А для онлайн дискуссий есть IRC.
rumkin
По поводу почты и прочего ответил выше.
А по поводу выбора мессенджера: сегодня 9 из 10 заказчиков на том же фрилансе предложат вам обсудить проект именно в Skype. А для работы над проектом, где совместно трудятся не только программисты, но и менеджеры, дизайнеры и прочие специалисты, удобнее slack сейчас нет. И это не ИМХО, а данность.
ИМХО – IRC – вещь для программеров.
ValdikSS
Но, согласитесь, почта действительно устарела как протокол. Все еще далеко не все серверы используют шифрование при передаче писем, SPF — костыль, а DMARC почему-то никто не использует, да и он не всегда подходит. Надеюсь, проекты вроде DarkMail войдут в мейнстрим.
IRC я тоже люблю, но он критически устарел: нет поддержки истории, невозможно сразу залогиниться после разрыва соединения, ограничение на длину сообщения, nickserv, chanserv, cp1251, cp1252.
Не понимаю, почему нет нормального хотя бы протокола, который описывал и шифрованное текстовое общение, и аудио/видеозвонки и конференции. Есть XMPP, который до сих пор нормально NAT не пробивает, из-за чего нельзя передавать файлы, с OTR, который не позволяет создавать шифрованные чаты, с Jingle, который поддерживают 2.5 клиента, и есть SIP, который позволяет неплохо звонить голосом и видео, и даже конференции, но который тоже не всегда пробивает NAT (даже ICE, бывает, не срабатывает), и с SIMPLE, который, опять же, поддерживают 2.5 клиента, и который ну очень простой, которого недостаточно для нормального IM.
Есть неплохие проекты на основе WebRTC, но они все в браузере.
BaRoN
Почта асинхронная, в этом её великое преимущество. Можно просто сесть и трижды в день разгрести что-то там.
А вот во всяких вотсаппах люди в основном ожидают немедленного ответа.
aleks_raiden
асинхронность хороша, когда вам надо реагировать на чужие запросы — тогда да. А если вы на месте спрашивающего?
BaRoN
Надо понимать, что если вы, спрашивающий, требуете немедленного ответа на ваше решение, вы как бы оцениваете этим своё время и свою проблему выше, чем время того, у кого вы это спрашиваете.
Если у вас есть на это право, то наверняка есть и канал срочной связи с тем, у кого спрашиваете. Зайти в соседний кабинет, позвонить, ещё какие-то другие варианты. Такие каналы нужно как-то сразу обговаривать с людьми, которые обязаны вам отвечать на любые ваши запросы немедленно.
NeonXP
XMPP свои функции уже кучу лет исправно выполняет. А на месте автора, я бы смотрел в сторону matrix.org.
P.S. заголовок слишком провокационный
dlap
подскажие, как нечто подобное прикрутить к тому, что бы переписка сохранялась на сервере? Или она в этом продукте уже сохраняется и я что то не допонял? заранее извиняюсь
NeonXP
Это не продукт сам по себе, а протокол, аля XMPP. Только построенный поверх привычных технологий, как HTTP REST JSON. Есть несколько реализаций серверов (http://matrix.org/blog/try-matrix-now/ раздел Homeservers) и клиентов (та же страница). Почему я привёл эту ссылку? Заголовок статьи звучит как «XMPP отстой». Мой ответ: «Раз вам(автору статьи) XMPP отстой, тогда посмотрите в сторону неотстойного Matrix.org»
P.S. сейчас в свободное время немного пилю свою реализацию Home Server. Стоит ли по результатам запиливать на хабр статью про сам протокол и мой сервер?
Balek
Однозначно стоит.
saggid
Протокол этот был изобретён еще в те времена, когда у людей не было по 15 разных гаджетов одновременно, и никто сильно и не заморачивался с синхронизацией переписки между ними. Обычно, у человека тогда был свой комп, да мобильник, и на этом список гаджетов заканчивался.
Для вашего решения наверное было бы более логично написать свой собственный простейший протокол, ведь вам там совсем немного надо было для своей задачи. А вы вместо этого попытались решить свою проблему через этакого монстра для общения из 2000-х годов :) Сами уж виноваты, это не вина XMPP-протокола.
4410 Автор
Абсолютно с этим согласен. Собственно, я почти это и написал в выводе. Протокол конечно из 2000-х годов, но это не отменяет того, что в 2010-ых он выглядит устаревшим, об этом и статья.
bormotov
Я знакомился с xmpp в тех самых 2000-ых и можнро считать, что уже всё забыл. Тем не менее, мы до сих пор продаем и эксплуатируем продукт, у которого внутри xmpp. Правда, людей это не касается вообще никак, сугубо внутренняя штука.
Так вот у меня ощущение (скорее всего ошибочное), что основной плюс протокола именно в том, что туда не очень сложно «докинуть» те возможности, которые нужны, при том, что некая основа уже есть готовая. Нужен вам архив сообщений — делайте. Нужно zzzz — делайте.
Но конечно это подразумевает, что
* потребуется допиливание сервера
* потребуется допиливание клиента
Альтернатива «полностью свой собственный код», не факт, что окажется выгоднее.
Общего решения тут нет, увы.
laphroaig
Если нужно пристрелить воробья, а есть только пушка, то имеет смысл изобрести рогатку
4410 Автор
Рогатка рисковала стать пушкой, учитывая все требования. И в этом свете изобретать пушку заново не очень хотелось.
mOlind
Так чем все закончилось? Вы решили писать свой велосипед или учить erlang?
4410 Автор
Взяли Tigase, вкрутили туда нужный код(это всё что касалось пометки сообщений как прочитанные/непрочитанные). Ещё немножко кода, использующего ту же самую базу вкрутили в само приложение(эндпоинт, который возвращает 30 последних сообщений от разных пользователей, грубо говоря список диалогов).
Louter
А зачем вообще XMPP? Приложение допускает (допускало) общение и с другими серверами и их клиентами (как в почте)? =)
4410 Автор
Нет, не допускало. В статье же есть причины почему выбрали.
HotIceCream
Жаль про выбор клиентов про мобильные мало)
Мы в свое время выбрали libjingle, аргументировав это тем, что используется в Google Talk и может собираться для iOS и Android.
Потом libjingle стала частью webrtc и ради нескольких мегобайт полезного кода библиотеки приходилось собирать половину хромиума.
А некоторые баги, на которые заведены таски несколько лет назад так и не пофикшены (с pull requests у гугла не очень хорошо).
Использовать существующие реализации XMPP на мобильных, наверное, не очень разумно. В последнее время рекомендуется делать доставку сообщений до клиента через что-то типо GCM, а не держать постоянное соединение с сервером.
Suvitruf
Статья должна называться «Как мы выбрали продукт (не проанализировав его возможности) который нам не подходит и жаловались потом на него», или, если почитать выводы статьи, «Никто не будет делать что-то за вас».
Ну да, это проще, чем написать модуль на Erlang/Elixir. Хотя, если чатом пользуются два с половиной человека, то да, возможно и проще.Btw,
Мне вот интересно, кластеризацию вы тоже будете писать сами?
4410 Автор
С одной стороны модуль написать звучит попроще, а с другой стороны для этого надо бы выучить этот самый Erlang.
Про кластеризацию можем поговорить, если хотите. Вижу две проблемы: горизонтальное масштабирование хранилища с сообщениями и пользователями и собственно пересылка сообщений между пользователями, если они подключены к разным серверам. Первая проблема уже решена: используем mongodb с шардингом. Вторая проблема решается при помощи Apache Kafka/RabbitMQ или другой очереди, по вкусу.
Suvitruf
Если у вас сервер станет недоступным, что произойдёт?
4410 Автор
Клиент потеряет соединение и переподключится по тому же адресу, и через load balancer попадёт на живой сервер.
silvansky
Ключевая буква — X. Расширяемый протокол. Даже слишком расширяемый… Глядя на список ксепов, можно сойти с ума. И уж понятно, что все opensource-сервера и клиенты писались авторами под свои специфичные нужды, а для Ваших нужд не нашлось, увы, подходящих реализаций.
Но это, как уже говорилось, не означает, что «XMPP отстой». Эдак можно говорить, что «XXX отстой», если не подходит под Ваши нужды. Яркие примеры: «винда отстой», «линукс отстой», «фряха отстой», «макось отстой», «Android остой», «iOS отстой» и так далее.
4410 Автор
Но ведь под мои нужды не нашлось не только реализаций, но и спецификации. А мои нужды ничем не отличаются от нужд любых других современных IM. Более корректно было бы сказать, что XMPP устарел или, как написали выше, решает другие задачи.
lolmaus
Чем offset и limit отличаются от start и max? :/
4410 Автор
Тем, что механизм со start и max заставляет нас брать этот самый start из последнего сообщения. С другой стороны у механизма с offset и limit тоже есть свои проблемы.
4410 Автор
Ну и в целом даже то, что есть позволяет вытаскивать сообщения по start и max только с определённым пользователем. То есть заранее нужно знать с каким пользователем сообщения вытаскивать. А чтобы узнать с какими пользователями вообще было общение вам нужно вытащить коллекции (термин самого XMPP, означает диалог с каждым отдельным пользователем, в каждый отдельный день) и как-то из них вычленить уникальных пользователей. Ну или вытягивать из отдельных коллекций.
mikhailian
Ну, offset и limit — это как бы моветон в мире SQL. Посмотрите хотя бы скажем вот эту статью. Если хотите горизонтально расти до миллионов пользователей в онлайне (ну скажем как World of Tanks), то offset вам очень сильно помешает. Так что start + max с точки производительности получше.
mikhailian
Блин, вот use-the-index-luke.com/no-offset
4410 Автор
Согласен, оно и в используемой нами MongoDBс точки зрения производительности работает ужасно и везде где можно используются похожие вещи. Согласен, насчёт start и max не прав, но механизм получения архива в целом довольно неудобный, в комментарии выше описал.
bolk
Моветон, ага, но все РБД имеют это в своём синтакисе. Потому что когда критерий сортировки не совпадает в возрастанием или убыванием айдишников, неясно как листать страницы.
mikhailian
Не все. В Oracle нет ни offset, ни limit. И это не потому, что Oracle — отстой.
bolk
Во-первых, ROWNUM — те же яйца, только боком.
Во-вторых, FETCH FIRST x ROWS ONLY / OFFSET y ROWS FETCH NEXT x ROWS ONLY
mikhailian
Ну кстати ROWNUM существует как раз для того, чтобы избежать проблемы с OFFSET. А проблема с OFFSET в том, что ему нужно слишком много рассчитать для того, чтобы вернуть совсем чуть-чуть.
bolk
Он ровно так же работает, как и LIMIT/OFFSET — результат нумеруется, потом по номеру отрезается, только в случае ROWNUM он нумеруется до сортировки, что добавляет проблем.
Karamax
Название стандарта XEP-0013 доставляет и раскрывает суть.
0xd34df00d
Выражаясь терминами вашего заголовка, разработчики у вас отстой. Следуя стилистике поста, скажу, что они почему-то не осилили перейти по ссылке из спеки на 0136 и почитать XEP-0059, в котором описана и семантика
<start>
, и<index>
упомянут, и так далее.А ещё через Message Carbons можно получать сообщения сразу на все ресурсы (или некоторые, какие сами выберут), через 0136 (или 0313, который сильно упрощает жизнь) синхронизировать историю, и, в общем, реализовать всё, о чём вы написали.
А ещё забавно, что заголовок у вас про XMPP, начали вы про XMPP, а закончили жалобами на конкретные реализации. Вам авторы протокола должны и реализации под ваши задачи подготовить, что ли?
Удивился, кстати, не увидев стандартных (и оправданных) жалоб на Jingle.
zhovner
А уведомления о прочтении в каком XEP описаны?
0xd34df00d
XEP-0333.
zhovner
Implementation of the protocol described herein is not recommended.
0xd34df00d
В силу того, что рассмотрение отложено, не более.
Практика показывает, что это не проблема. Особенно если речь идёт о собственной, закрытой инфраструктуре, что, как я понимаю, во многом случай топикстартера.
4410 Автор
Какой полезный комментарий. Давайте по-порядку.
Обе спеки что вы скинули deferred соответственно абсолютно бесполезны.
Message Carbons доставит только на подключенные устройства.
В статье есть часть про сам протокол и часть про сами реализации. Вы считаете что надо было сделать как-то иначе?
0xd34df00d
Спасибо, в полезных комментариях я мастерство!
Как лично вам мешает deferred? Как вы из этого делаете вывод, что они абсолютно бесполезны? Что message carbons, что MAM реализованы в том же Prosody, например, и в ряде клиентов, включая мой, так что как минимум уже не абсолютно.
Message Carbons, конечно, только на подключённые, как я и написал в исходном комментарии. Поэтому я и упомянул отдельно 0136 и 0313 для довытаскивания той части истории, что получилась, пока устройство было оффлайн. Вы это, видимо, тоже не прочитали :(
Кстати, есть ещё более наркоманские и хардкорные расширения, позволяющие замораживать и сохранять поток между клиентом и сервером. Пользователям мобилочек будет полезно. Но я их не осилил, поэтому ссылок не помню, кроме 0198.
Я считаю, что реализации — это отдельная история, про которую можно говорить бесконечно. Кривость реализаций лишь в малой мере обусловлена кривостью протокола.
4410 Автор
Мне лично никак не мешает deferred. Как и сами спеки, впрочем, никак не помогают.
Не понимаю зачем вы упоминали MAM (в статье про него есть, кстати) и Message Carbons (про онлайн сообщения в статье ничего плохого не сказано) вообще. Они не решают проблемы, работа с историей в XMPP даже с упомянутыми вещами — абсолютный геморрой, о чём я писал тут.
В статье я описал в целом о работе с протоколом, и по-моему реализации это очень важная часть темы. И да, я не утверждал, что кривость реализаций обсусловлена кривостью протокола.
0xd34df00d
Так, значит, не абсолютно бесполезны, получается?
В статье есть ссылка только на 0136, но не на 0313, разве нет?
Да, невозможность вытянуть список пользователей, для которых сохранена история, по крайней мере, через 0313, несколько печалит.
С другой стороны, вы всегда можете вытаскивать историю, начиная с какой-то даты после начальной синхронизации. Это вкупе с возможностью постраничной навигации по пользователям, ИМХО, покрывает подавляющее большинство юзкейсов.
4410 Автор
Не помогают — нулевая полезность.
Нет, зато в комментарии упоминаю, что и он — не панацея.
С вашей схемой при логине с нового устройства будут происходить забавные вещи.
0xd34df00d
То «deferred следовательно абсолютно бесполезны», то не «Не помогают — нулевая полезность». Ладно.
А какие вещи там будут происходить забавные? А какой юзкейс вы вообще рассматриваете, опять же?
4410 Автор
Хм, возможно неправильно вас понял. Но мне казалось что при логине с нового устройства будет происходить синхронизация всех-всех сообщений. Вообще эту проблему временно решили написав эндпоинт, который собирает уникальные диалоги в истории сообщений. С точки зрения производительности решение ужасное, но пока работает сносно.
0xd34df00d
Так а что вам нужно-то? Поддерживать локально актуальную версию всей истории, отображать исторические диалоги по собеседникам, или что-то ещё?
В первом случае много-много всего всё равно прожевать придётся, какой бы протокол ни был (и XMPP этому не препятствует в обоих ипостасях из 0313 и 0136), во втором — ну так вы уже знаете ID контакта, когда пользователь тыкнул в кнопку истории с этим контактом.
Есть, конечно, третий вариант, когда вы просто хотите, условно, отдельным окном показать всех тех, с кем есть непустая история, но это ИМХО весьма редкий случай, да и решаемый в XMPP, пусть и за линейное по размеру ростера время.
4410 Автор
Нам нужно показать список последних диалогов пользователя, сортировка должна быть по дате последнего сообщения в диалоге с последним сообщением и пометкой есть в этом диалоге непрочитанные сообщения. Заранее ID контакта не знаем.
0xd34df00d
А, тогда только костылять, да, что печально.
Вот ведь интересно, меня очень похожий момент в своё время смущал в 0313, вас он вот смущает, но лично я так и не собрался и не написал в мейллист XMPP с предложением это дело исправить. Вы, подозреваю, тоже.
Так и будем поэтому :(
0xd34df00d
Впрочем, почитал ещё раз спеку на 0313 — там можно целыми формами поиск устраивать (часть 4.1.5). Вероятно, с допиливанием сервера, это может вам помочь.
4410 Автор
Ну не совсем, это, насколько я понял, поиск по кастомным полям.
safron
а может вот это будет получше?