Серия «История разработки: Mercury Messenger»

6

История разработки мессенджера Mercury, часть 2: полный P2P⁠⁠

Серия История разработки: Mercury Messenger

Две хорошие новости для любителей интернета, технологий, мессенджеров и дневников разработки.

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

Первая версия мессенджера, про которую был предыдущий пост, работала на технологии WebRTC: это хорошо проработанный набор протоколов для установления прямого соединения между устройствами через интернет и передачи текстовой/бинарной и медиа информации, такой как голос и видео. WebRTC настолько популярен, что, в общем-то, все видеоконференции сейчас работают на этом фреймворке - его поддержка вшита во все браузеры а для мобильных разработчиков поставляются и регулярно обновляются готовые библиотеки. Если очень кратко, два клиента, которые хотят установить прямое соединение, получают информацию о своем присутствии в интернете от STUN-сервера (сокр. от англ. Session Traversal Utilities for NAT, это сетевой протокол, который позволяет клиенту определить свой внешний IP-адрес, способ трансляции адреса и порта во внешней сети) и публикует все что нашел на особом сигнальном сервере. Сигнальный сервер для обоих клиентов должен быть один и тот же, а STUN-сервера - какие угодно, их много публичных и бесплатных.

Проблемы начинаются, когда один или оба клиента спрятаны за NAT (Network Adress Translation, это технология, которые используют роутеры чтобы преобразовать адреса внутренней сети в адреса интернета и обратно) и входящие соединения невозможны, то есть в современном интернете - практически всегда. Для того, чтобы устройства все-таки смогли как-то установить соединение, WebRTC предполагает использование TURN-серверов (Traversal Using Relays around NAT), специальных реле, которые передают зашифрованные аудио/видео/данные потоки между устройствами когда прямое соединение не может быть установлено. Для своего приложения я использовал TURN-сервера от metered.ca.

Когда я опубликовал первую версию мессенджера, внезапно обнаружилось, что metered.ca в России заблокирован, давно и прочно. Общение не задалось.

Так вот, первая хорошая новость - я, наконец-то, полностью, окончательно и бесповоротно (потому что я никогда не возьмусь переделывать это взад) перевел мессенджер на libp2p. Это открытый фреймворк для разработки P2P приложений, со встроенным шифрованием, обходом NAT и поиском клиентов в распределенных хэш-таблицах. libp2p подразумевает, что где-то в интернете должны быть доступны стартовые ноды с известными адресами, а дальше по мере роста количества клиентов, распределенная сеть будет становиться все устойчивее и устойчивее. Пока я выкатил 4 стартовые ноды, и, если их заблокируют, я легко смогу перевыпустить их с новыми адресами и обновить приложение.

Япония, к слову, не блокирует ничего пока, там и первая версия работала. Но обновленная - намного лучше.

libp2p работает немного похоже на WebRTC но есть и принципиальные отличия. Например, когда клиент ААА хочет установить соединение с клиентом АББ, в случае WebRTC этим занимался сигнальный сервер - он знал контактные данные обоих клиентов и дружил их друг с другом:

WebRTC

WebRTC

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

Аудио и видео звонки я оставил работать через WebRTC, для этого в свои ноды я добавил встроенный TURN-сервер на основе открытого coturn. Так как контакты обоих устройств уже известны - вы не можете позвонить не установив соединение - сигнальный сервер не нужен. 4 слабеньких ноды - это, конечно, не панацея, но пару сотен одновременных звонков выдержат. В теории, если надо, и для усиленной безопасности, люди смогут публиковать в интернете свои собственные ноды - и привязать их к приложению, это все уже реализовано.

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

Ноды можно запускать как простым бинарником, так и в докере. Потом как-нибудь сделаю линукс сервис.

Ноды можно запускать как простым бинарником, так и в докере. Потом как-нибудь сделаю линукс сервис.

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

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

Другие темы для будущих постов
Всего голосов:

Если захотите пощупать это приложение самостоятельно, ссылку на Google Play я оставлю в комментариях.

Показать полностью 7 1
13

Как написать собственный мессенджер и сохранить рассудок⁠⁠

Серия История разработки: Mercury Messenger

Где-то с полгода назад, когда началась эта история с блокировками и замедлением, я задался вопросом: "Ведь скоро заблокировано будет чуть более, чем всё. А как мне, собственно, при этом всём общаться с семьей и друзьями, когда я живу заграницей, а они в России?". Я вышел в интернет с таким вопросом, и начал поиски удобного надежного мессенджера, чтоб чисто писать, звонить и скидывать мемы. Несколько вариантов нашлись довольно быстро, какие-то заработали у родителей, какие-то нет, парочка отвалилась в процессе тестирования, в общем, это не особо важно, уже даже на Пикабу встречал несколько обсуждений, так что обойдемся без подробностей.

Во время всего этого священнодействия, меня не отпускала одна мысль. А чего бы не сделать свой мессенджер? Опыт есть, в прошлом я плотно занимался разработкой под Андроид по работе, да и своих личных приложений опубликовал с десяток. Тем более, у меня уже есть свое родное приложение для видеоконференций, peer-to-peer: прямое соединение от устройства до устройства, никаких лишних серверов, одна красота. Ну разве что надо будет заменить конференции на звонки, прикрутить к нему список контактов, чаты, профили, криптографию, аутентификацию, цифровые подписи, подтверждения и удаления контактов, базу данных, индексы, миграции, транзакции, пейджинг, навигацию, передачу сообщений, файлов, уведомления, настройки, поиск, блэклист, потом интегрировать все это великолепие со службами телеком Андроида, добавить просмотр картинок и видео, тесты, ботов, шэринг, перевести на основные мировые языки. Что может быть проще?

Проще, конечно, не было. Весь процесс занял почти 5 месяцев.

Проще, конечно, не было. Весь процесс занял почти 5 месяцев.

За 5 месяцев работы по вечерам и выходным (ну, конечно, не каждый день), 543 коммита и примерно 40000 строк кода, получилось что-то более-менее удобоваримое и стабильное.

Так как человек я бедный экономный, и не планирую поддерживать дорогую серверную инфраструктуру, даже чаты в моем приложении работают через p2p - прямое соединение между телефонами. Это, кстати, редкость среди публично доступных мессенджеров, подавляющее большинство используют сервис пуш-уведомлений Гугла или Эппл для доставки сообщений. В моем случае, сначала оба устройства устанавливают прямое соединение друг с другом, и только в случае успеха начинают обмениваться шифрованными мемами со страшной силой без промежуточного сервера. Если соединиться прямо сейчас не удалось, все будет локально сохранено и доставлено автоматом при первой же возможности. Кое-какой обмен с сервером для установления прямого соединения все равно необходим - телефоны должны обменяться информацией о своем подключении и IP-адресах, но как только соединение установлено - сервер можно даже выключить - общению это не помешает.

И в этом заключается как огромное преимущество, так и некоторые недостатки: переписки и звонки мало того что закодированы сквозным шифрованием, так еще и никогда даже не попадают на сервер - это чертовки приватно и секьюрно и не надо сильно беспокоиться об утечках - невозможно слить то, чего нет. С другой стороны, теперь конечные устройства ответственны за доставку текстовых сообщение и пакетов данных - сам телефон должен организовать повторную доставку, если что пошло не так, для всех переписок. Это не проблема вовсе для частных контактов, небольшая трудность для групповых чатов на 50-100 человек, но огромная головная боль для публичных каналов на миллионную аудиторию. Публичных каналов, поэтому, нет. Групповых чатов, впрочем, тоже пока нет.

Чтобы добавить кого-то в свой список контактов нужно просканировать QR-код с временным криптоключём, или добавить по идентификатору и ждать, пока тот вручную подтвердит добавление и клиенты обменяются цифровыми подписями.

Чтобы добавить кого-то в свой список контактов нужно просканировать QR-код с временным криптоключём, или добавить по идентификатору и ждать, пока тот вручную подтвердит добавление и клиенты обменяются цифровыми подписями.

Эта девстори не была бы полной, если бы я не упомянул о самом трудоемком (да и самом интересном). Я ж ниибаца профессионал, на работе я делаю софт, которым пользуются миллионы, весь такой safety-critical С++ покрытый на 100% тестами и анализаторами по самую макушку. Нельзя же просто взять и сделать Ардроид приложение, это слишком просто, надо извернуться и с самого начала создать целый фреймворк для мессенджеров.

Я разработал С++ ядро, единое для всех поатформ, а приложение Андроид должно по задумке быть только тонким клитентом вокруг этого ядра. Забегая вперед, скажу что задумка удалась почти полностью. Конечное приложение действительно работает как оболочка вокруг единого производительного и набитого тестами ядра, и если я захочу сделать приложение, например, для Эппл, мне нужно будет только скопировать пользовательский интерфейс, биндинги на ядро и интеграцию с родными службами айфона. Вся логика, настройки, все модели, хранилище, шифрование и вообще всё-всё - уже в ядре. Это здорово, но насколько же все усложнилось, кто бы знал. Тем не менее, оно работает, и в общем, работает весьма неплохо, потребление приложением батареи за день на фоне всего остального вообще не заметно. Есть еще поле для оптимизации хранения в базе данных, да и ядро можно порефакторить во имя вечного и недостижимого приближения к идеалу, но в целом и так хорошо.

Надеюсь, понятно и без перевода. Если кратко - батарею не жрёт.

Надеюсь, понятно и без перевода. Если кратко - батарею не жрёт.

Итого, получилось довольно неплохое приложение для общения. Уже больше недели я с семьей и друзьями используем его для ежедневных переписок и пока все всех устраивает и, более того, нравится. Настолько, что я решил выложить мессенджер в Google Play, а мою девстори прямо сюда. Для желающих скачать и потрогать, ссылка вот https://play.google.com/store/apps/details?id=hela.eillance, там нет рекламы, нет подписок и платного контента. И вряд ли когда-либо будет, добавлять рекламу или подписку в мессенджер, когда вокруг столько бесплатных альтернатив (как, например, поддерживаемый на государственном уровне, MAX/sarcasm), это просто приговор.

Кстати, не переименовать ли мне его в Sarcasm Chat?

Показать полностью 5
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества