Comments 42
Ну что сказать... Если это не фейк и будет опубликовано под вменяемой лицензией, то ДАЙТЕ ДВА
В принципе, а почему бы и сейчас не открыть. Точно не фейк, можно проверить
я недавно сделал такой же на С++, правда совершенно с другими решениями, но всё же. Наверное менее замороченный в плане шифрования и более низкоуровневый. Например в статье совсем не упоминается как кодируется звук, вероятно готовая библиотека используется
Использовалась библиотека sea, но возникли проблемы с линковкой зависимостей под windows. Сейчас там 2 кодека - raw и ADPCM, реализацию можно найти в репозитории.
Во всех примерах показывающих использование WebRTC как правило, парочка концептов подобных P2P мессенджеров имеется. Так что если конкретно это и фейк), аналогичного добра в интернетах навалом.
Но конечно же есть нюанс, и не один, и даже не два)
Грандиозно! Ждем открытия проекта.
Я бы расширил список хабов, хотя бы добавил Криптографию. Иначе никто не увидит статью.
На парковке будет ловить?
Почему решили писать свое решение для обхода NAT вместо готовых решений, таких как libp2p? Он поддерживает больше вариантов обхода, включая udp hole punching, который может не работать в силу другой реализации NAT на роутере.
Ещё не совсем понятно как создать чат с нужным человеком. Будет поиск по имени, только по username, по user-id, или по public key (привет tox)?
libp2p, когда я на нее смотрел, была жестоким оверинжинерингом. Это от туда потом пошли мемы про Томаку
Я рассматривал libp2p, но на момент рассмотрения у меня не было глубоких знаний (проверенных на практике) и хотелось получить минимальный рабочий вариант без сложных зависимостей, с максимальным контролем и пониманием происходящих процессов. В текущей реализации есть один изьян - соединения не работают при включенном VPN (возможно у меня такой попался, но это вроде распространенный случай). Сейчас планирую добавить TURN, это должно покрыть все возможные случаи, а дальше уже понять, что нужно ли переходить на libp2p (библиотека очень обширная).
Насчет создания нужного чата - нужно знать публичный ключ собеседника (точнее хеш от ключа). Дальше собеседник решит принять от вас запрос или нет. Тут да, как в tox или jami. Метаинформация о контактах нигде, кроме как между собеседниками не хранится, и искать другими способами не получится.
Спасибо! С большим интересом почитал.
А не рассматривали QUIC как вариант транспорта поверх udp?
Когда реализовывал транспорт я смотрел на спецификацию quic чтобы почерпнуть немного идей. Однако руки еще не дошли изучить как обстоят дела с реализацией quic для rust и насколько его реалистично адаптировать к p2p.
Cloudflare достаточно давно открыли библиотеку quiche, совсем недавно они выкатили адаптер tokio-quiche.
Прикольно, но я бы дальше отказался от bincode, это хорошо для прототипа, но в нем ты хрен сделаешь forward и backward compatibility.
Тут что-то типа protobuf подойдёт, ну или надо посмотреть что нового в расте есть, postcard вот неплох, но это аналог bincode
Такое уже есть. Вряд ли получится наколхозить что то лучшее чем https://jami.net/ru/
А вы им пользовались? Перед тем как что-то колхозить, были попытки подружиться в том числе и с Jami. К сожалению, с простыми звонками ничего не вышло: у меня и у собеседника были те же проблемы - постоянно надо дергать аудио, чтобы нужное устройство ввода/вывода использовалось, прерывания звонков. Для моих целей Jami как и Tox, не подошел на тот момент.
Это понятно но сможешь ли ты сделать лучше не полагаясь целиком и полностью на свой маленький релей сервер? Стоит ли заморачиваться с п2п если всё равно всё зависит от сервера на 146%.
К тому же p2p позволяет узнать IP пользователя всем заинтересованным.
сможешь ли ты сделать лучше не полагаясь целиком и полностью на свой маленький релей сервер
Да, в моем случае уже получилось лучше, чем Jami, в плане работоспособности. Если говорить про OpenDHT, то интеграция возможна, но это задача низкого приоритета, поскольку мой текущий подход уже решает основные проблемы.
Стоит ли заморачиваться с п2п
Стоит, ведь P2P подразумевает прямое соединение между собеседниками (в случаях когда это возможно), которое ограничено только пропускной способностью канала собеседников, а не сервера.
Что Вы скажете насчет Tox?
Проблема только со звонками?
Как он в целом?
Ничего плохого сказать не хочу. Из моего опыта - нестабильная работа (креши) и проблемы со звонками (неявные разрывы). При неправильном использовании интерфейса - переход в такое состояние, из которого можно выйти только перезапуском приложения. Функция "поделиться экраном" сделана довольно оригинально - через видеозвонки и переопределение в настройках устройства камеры на область экрана. Правда, помимо оригинальности, смотреть демонстрацию было довольно проблематично. Вполне возможно, что за два месяца проблемы исправили, или же проблемы были именно у меня, а не в приложении.
Запускать-то сервер, наверное хорошо, но как пользоваться этим непонятно. Ну вот оно висит на 8080 порту и куда дальше-то? Смотреть как загораются тесты?
Ну, и автор кажется не очень понимает как работает лицензирование. MIT/Apache явным образом разрешают коммерческое использование и добавление Common Clause приводит к легальному противоречию, что фактически инвалидирует его. Не проще было сделать код каким-нибудь GPL в таком случае для некоммерческого использования (например, двойное лицензирование AGPL + коммерческая лицензия)?
А почему не используются UUIDv7 "для упорядочивания сообщений в пользовательском интерфейсе"? Они же последовательные, если генерятся одним процессом! Для Rust рекомендую Uuid::now_v7(). См. также статью разработчика этого метода.
А вот log_id - это явно лишний идентификатор.
Есть две проблемы, почему здесь не используется только message_id (который генерируются UUIDv7):
В распределенной системе нет гарантии, что у обоих участников часы синхронизированы.
Сообщение может быть составлено и отправлено на устройстве пользователя в момент плохого соединения или вообще, отсутствия соединения с собеседником. В результате сообщение может быть доставлено со значительной задержкой.
log_id позволяет сериализовать запись каждого сообщения не зависимо от времени, гарантируя что у каждого собеседника история является append-only.
Остается ощущение чрезмерно избыточного количества разных типов идентификаторов в сообщении (id, message_id и log_id). Я совершенно уверен, что можно было бы обойтись только message_id (UUIDv7), а процедура разрешения конфликтов при этом была бы вообще не нужна.
Я хочу напомнить, что таймстемп в UUIDv7 - это по сути Всемирное координированное время (UTC), не зависящее от часового пояса, но только отсчитываемое не от 0 года, а от 1970 года в миллисекундах. В каких бы точках планеты не находились участники переписки, у них на часах устройства одно и то же время UTC. Поэтому не нужна никакая синхронизация часов участников - сейчас все компьютеры и телефоны синхронизированы с UTC достаточно точно для мессенджера. Максимальная погрешность в 100 миллисекунд воспринимается человеком как мгновение.
Если сообщения отсортировываются в интерфейсе по message_id (UUIDv7), то это значит, что они отсортированы по моменту отправки. Если сообщение пришло со значительной задержкой, то оно встанет в середину беседы, и его можно выделять как непрочитанное, пока пользователь не уберет его с экрана.
Насколько я понял, процедура разрешения конфликтов полагается на то же самое время UTC отправки сообщения. То есть результат (последовательность сообщений) точно такой же, как и при сортировке по message_id (UUIDv7).
Аська
Как следствие вопросы:
Как peer узнает про другой peer? Совсем serverless не получится.
Что делать если destination peer offline? Не принимать? Аська такие к себе на сервер отправляла.
Если это постоянный socket, то при постоянном соединении с сотней других peer спать сервис не будет никогда, то есть для смартфона не применимо.
Чтобы peer узнал о другом peer, нужен третий участник (в данной статье это ntied-server). Serverless не получится, я даже не знаю, возможно ли здесь достичь serverless, при отсутствии статического белого IP хотя бы у одного участника.
Если участник не в сети, то сообщение попадает в очередь и потом когда-нибудь, когда оба участника в сети, будет доставлено. Здесь нет сервера для таких случаев, я не решал пока такую проблему.
А будет ли это приложение работать в фоне? Я протестировал Jami, и там эта функция реализована через Google Firebase. И в чём отличие вашей архитектуры звонков от Jami и Tox? Ведь там они тоже p2p
Ещё бы скриншотов добавить в README на гитхабе и в статью, и было бы прекрасно)
Клиента на веб страницу получится воткнуть? Если нет, то рекомендую подумать в сторону создания JS биндингов.
Очень много рассказано про NAT, это хорошо. Но что с поддержкой IPv6? Ведь если смотреть по миру, больше 50% трафика ходит по v6. Можете дописать в статье как P2P пользователи связываются в различных связках дуалстеков и синглстеков?
Подскажите, что почитать по этой теме? Я половину не понимаю (не раст)
Разработка peer-to-peer мессенджера на Rust