298 lines
7.4 KiB
Markdown
298 lines
7.4 KiB
Markdown
# XMPP Messenger (Text + Voice Messages)
|
||
|
||
## 1. Цель документа
|
||
|
||
Этот документ предназначен как **техническое задание и дизайн‑документ** для разработки XMPP‑мессенджера с поддержкой:
|
||
- текстовых сообщений
|
||
- голосовых сообщений (аудиофайлы, без стриминга)
|
||
- end‑to‑end шифрования
|
||
- iOS и Android клиентов на React Native
|
||
|
||
Документ рассчитан на использование **Claude Code** как основного помощника в реализации. Поэтому архитектура и формулировки сделаны максимально явными, модульными и детализированными.
|
||
|
||
---
|
||
|
||
## 2. Область и ограничения
|
||
|
||
### Входит в scope
|
||
- One‑to‑one чаты
|
||
- Текстовые сообщения
|
||
- Голосовые сообщения как файлы
|
||
- E2EE (OMEMO)
|
||
- Собственная XMPP‑инфраструктура
|
||
|
||
### Не входит в scope
|
||
- Голосовые/видео звонки
|
||
- Групповые чаты (MUC)
|
||
- Push‑нотификации (опционально позже)
|
||
- Федерация между серверами (пока один домен)
|
||
|
||
---
|
||
|
||
## 3. Общая архитектура
|
||
|
||
```
|
||
Clients (iOS / Android)
|
||
|
|
||
| XMPP over WebSocket
|
||
|
|
||
XMPP Server (Prosody)
|
||
|
|
||
| HTTP Upload
|
||
|
|
||
File Storage (local / S3)
|
||
```
|
||
|
||
- XMPP используется **только для сигналинга и сообщений**
|
||
- Голосовые сообщения передаются как **зашифрованные файлы** через HTTP Upload
|
||
- Сервер не имеет доступа к содержимому сообщений
|
||
|
||
---
|
||
|
||
## 4. Структура репозитория
|
||
|
||
```
|
||
./README.md — описание проекта
|
||
|
||
./doc/
|
||
design.md — этот документ
|
||
|
||
./server/
|
||
prosody/
|
||
prosody.cfg.lua — конфигурация сервера
|
||
modules/ — кастомные модули (если нужны)
|
||
deploy/
|
||
docker-compose.yml — развертывание
|
||
init.sh — инициализация
|
||
|
||
./react-native-lib/
|
||
src/
|
||
xmpp/ — XMPP логика
|
||
crypto/ — OMEMO / шифрование
|
||
audio/ — запись и воспроизведение
|
||
storage/ — работа с файлами
|
||
ui/ — общие UI компоненты
|
||
types/ — общие типы
|
||
|
||
./react-native-ios/
|
||
ios/ — iOS проект
|
||
App.tsx — точка входа
|
||
|
||
./react-native-android/
|
||
android/ — Android проект
|
||
App.tsx — точка входа
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Серверная часть
|
||
|
||
### 5.1 Выбор сервера
|
||
|
||
- **Prosody** (Lua)
|
||
- Причины:
|
||
- простой
|
||
- модульный
|
||
- хорошо документирован
|
||
- легко дорабатывается
|
||
|
||
### 5.2 Основные XEP
|
||
|
||
| XEP | Назначение |
|
||
|----|-----------|
|
||
| XEP-0030 | Service Discovery |
|
||
| XEP-0198 | Stream Management |
|
||
| XEP-0363 | HTTP File Upload |
|
||
| XEP-0384 | OMEMO |
|
||
| XEP-0313 | MAM |
|
||
| XEP-0280 | Message Carbons |
|
||
|
||
### 5.3 HTTP File Upload
|
||
|
||
- Хранение файлов:
|
||
- локально (MVP)
|
||
- либо S3‑совместимое хранилище
|
||
|
||
- Ограничения:
|
||
- max размер: 10 MB
|
||
- max длительность: 5 минут
|
||
|
||
### 5.4 Безопасность
|
||
|
||
- TLS обязателен
|
||
- Сервер **не логирует содержимое сообщений**
|
||
- Логи — только технические (connect/disconnect)
|
||
|
||
---
|
||
|
||
## 6. Клиентская часть (общая)
|
||
|
||
### 6.1 Технологии
|
||
|
||
- React Native
|
||
- TypeScript
|
||
- xmpp.js
|
||
|
||
### 6.2 Архитектура клиента
|
||
|
||
```
|
||
UI
|
||
↓
|
||
Chat Logic
|
||
↓
|
||
XMPP Service
|
||
↓
|
||
Crypto Layer (OMEMO)
|
||
```
|
||
|
||
Каждый слой изолирован.
|
||
|
||
---
|
||
|
||
## 7. Текстовые сообщения
|
||
|
||
### Flow
|
||
|
||
1. Пользователь вводит текст
|
||
2. Текст шифруется OMEMO
|
||
3. Отправляется XMPP <message/>
|
||
4. Получатель расшифровывает
|
||
|
||
### Формат
|
||
|
||
```xml
|
||
<message to="jid" type="chat">
|
||
<encrypted xmlns="eu.siacs.conversations.axolotl">
|
||
...
|
||
</encrypted>
|
||
</message>
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Голосовые сообщения
|
||
|
||
### 8.1 Аудиоформат
|
||
|
||
- Кодек: **Opus**
|
||
- Контейнер:
|
||
- Android: OGG / WebM
|
||
- iOS: AAC (fallback)
|
||
|
||
### 8.2 Flow голосового сообщения
|
||
|
||
1. Запись аудио
|
||
2. Кодирование
|
||
3. Шифрование файла
|
||
4. Upload через XEP‑0363
|
||
5. Отправка XMPP сообщения со ссылкой
|
||
|
||
### 8.3 XMPP сообщение
|
||
|
||
```xml
|
||
<message>
|
||
<body>Voice message</body>
|
||
<reference xmlns="urn:xmpp:reference:0" type="data" uri="https://upload/...">
|
||
<media-sharing xmlns="urn:xmpp:sims:1">
|
||
<file>
|
||
<media-type>audio/ogg</media-type>
|
||
<size>12345</size>
|
||
<duration>12</duration>
|
||
</file>
|
||
</media-sharing>
|
||
</reference>
|
||
</message>
|
||
```
|
||
|
||
### 8.4 UX требования
|
||
|
||
- запись по удержанию кнопки
|
||
- отмена свайпом
|
||
- отображение длительности
|
||
- ручное воспроизведение
|
||
|
||
---
|
||
|
||
## 9. Шифрование (OMEMO)
|
||
|
||
### Требования
|
||
|
||
- Использовать готовую библиотеку
|
||
- Один identity key на устройство
|
||
- Поддержка multi‑device
|
||
|
||
### Поток
|
||
|
||
- Файл шифруется симметричным ключом
|
||
- Ключ передается через OMEMO
|
||
|
||
---
|
||
|
||
## 10. iOS‑специфика
|
||
|
||
- Background mode: audio
|
||
- Permissions:
|
||
- microphone
|
||
- network
|
||
|
||
- Использовать native modules для записи
|
||
|
||
---
|
||
|
||
## 11. Android‑специфика
|
||
|
||
- Foreground service при записи
|
||
- Runtime permissions
|
||
- Ограничения Android 13+
|
||
|
||
---
|
||
|
||
## 12. Ошибки и edge cases
|
||
|
||
- потеря сети во время upload
|
||
- повторная отправка
|
||
- битые ссылки
|
||
- несовпадение ключей OMEMO
|
||
|
||
---
|
||
|
||
## 13. Нефункциональные требования
|
||
|
||
- запуск MVP < 5 секунд
|
||
- запись без UI лагов
|
||
- батарея: запись ≤ 5% / минута
|
||
|
||
---
|
||
|
||
## 14. README.md (кратко)
|
||
|
||
README должен содержать:
|
||
- описание проекта
|
||
- как запустить сервер
|
||
- как запустить iOS / Android
|
||
- ограничения
|
||
|
||
---
|
||
|
||
## 15. Возможные расширения
|
||
|
||
- Push notifications
|
||
- Groups (MUC)
|
||
- Voice calls (Jingle + WebRTC)
|
||
- Desktop client
|
||
|
||
---
|
||
|
||
## 16. Критерий готовности MVP
|
||
|
||
- iOS и Android обмениваются:
|
||
- текстом
|
||
- голосовыми
|
||
- сообщения шифрованы
|
||
- сервер не знает содержимое
|
||
|
||
---
|
||
|
||
**Этот документ считается достаточным для полной реализации проекта без дополнительных уточнений.**
|
||
|