Skip to content

Архитектура

Программа csend состоит из нескольких модулей, каждый из которых отвечает за свою задачу. Представь это как конструктор LEGO — каждый кубик делает что-то одно, а вместе они образуют целое приложение.

Общая схема модулей

plantuml Diagram

Что делает каждый модуль

main.rs — Диспетчер

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

csend send photo.jpg   →  вызывает send.rs
csend recv 3-royal...  →  вызывает receive.rs
csend tui              →  вызывает tui/mod.rs
csend (без аргументов) →  вызывает tui/mod.rs

Также настраивает логирование: обычно выводит предупреждения и ошибки (уровень warn), с флагом --verbose — всё подряд (уровень debug).

code.rs — Генератор кодовых фраз

Создаёт и обрабатывает кодовые фразы вроде 3-royal-mount-dance.

ФункцияЧто делаетПример
generate_code()Генерирует случайную фразу"7-castle-river-bloom"
code_to_room_id()Хеширует фразу → ID комнаты"a3f8b2c1e9d04567"
code_to_encryption_key()Выводит ключ шифрования[u8; 32] (256 бит)

protocol.rs — Словарь сообщений

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

Подробнее: Протокол передачи

send.rs — CLI-отправка

Режим csend send файл1 файл2: создаёт P2P-рой, генерирует кодовую фразу, показывает её в терминале и ждёт подключения получателя. После завершения передачи процесс автоматически завершается.

receive.rs — CLI-приём

Режим csend recv 3-royal-mount-dance: создаёт P2P-рой, ищет отправителя через mDNS (таймаут — 60 секунд), проводит рукопожатие и принимает файлы в текущую директорию.

network.rs — Строитель сети

Собирает libp2p-«рой» (swarm) — штуку, которая умеет находить соседей и обмениваться сообщениями. Настраивает два поведения (SendBehaviour): mDNS для обнаружения и request-response для обмена JSON-сообщениями. Все ограничения (16 MiB на сообщение, 600 с таймаут) задаются здесь.

transfer.rs — Мотор передачи

Собирает файлы (collect_files()), шифрует чанками по 256 КиБ (encrypt_chunk()), отправляет и принимает с расшифровкой (decrypt_chunk()). Использует трейт TransferProgress для отчёта о прогрессе — в CLI это вывод в консоль, в TUI — обновление прогресс-бара.

Подробнее: Безопасность

Как модули общаются

Модули не вызывают друг друга напрямую (это создало бы «спагетти-код»). Вместо этого они общаются через каналы — как почтовые ящики.

plantuml Diagram

Каждый канал — это пара:

  • Отправитель (tx) — кладёт сообщение в ящик
  • Получатель (rx) — забирает сообщение из ящика

Типы каналов:

КаналНаправлениеЧто передаёт
DiscoveryCommandApp → DiscoveryTask«Объяви файлы», «Убери объявление», «Обнови»
DiscoveryEventDiscoveryTask → App«Нашёл отправителя», «Нашёл получателя», «Отправитель ушёл»
P2pCommandPane → P2P Task«Принять», «Отклонить», «Завершить»
P2pEventP2P Task → Pane«Подключён», «Прогресс 45%», «Готово»

Паттерн «Outbox» — очередь уведомлений

Панели (SendPane, ReceivePane, NavigatorPane) не могут напрямую управлять фоновыми задачами. Вместо этого они складывают уведомления в «outbox» (почтовый ящик), а App забирает их на каждом тике:

plantuml Diagram

Главный цикл TUI

TUI работает как часы — каждые 80 миллисекунд (12.5 раз в секунду) выполняется один «тик»:

plantuml Diagram

Параллельные «рои» (Swarms)

Ключевой архитектурный момент: у каждого устройства работает несколько отдельных libp2p-роёв одновременно. Каждый рой — независимая P2P-сеть с собственным ID.

plantuml Diagram

Почему отдельные рои?

  1. Изоляция — долгая передача (например, фильма на 4 ГБ) не блокирует обнаружение новых устройств. Discovery продолжает работать, пока P2P-рой занят чанками.
  2. Параллелизм — можно одновременно отправлять файлы нескольким получателям, каждый в своём рое.
  3. Чистый жизненный цикл — P2P-рой создаётся при начале передачи и уничтожается после неё, освобождая ресурсы (порт, mDNS-запись, память).
  • Discovery Swarm — живёт всегда, пока TUI открыт. Объявляет наши файлы, слушает чужие.
  • P2P Swarm — создаётся на каждую передачу и умирает после неё. Занимается тяжёлой работой: рукопожатие, шифрование, передача чанков.