Соціальні функції в мобільних додатках: чат, VoIP, лента та реакції
Додати чат в додаток — це не «використовувати Socket.io та відображати повідомлення». Це офлайн-доступ, відображення історії при поганому з'єднанні, індикатори друку, статуси прочитання, push-сповіщення при закритому додатку, та все це повинно працювати на Android 8 з 512MB RAM без ANR.
Архітектура чату: WebSocket, XMPP, або готовий SDK
WebSocket — протокол, не архітектура. Голий WebSocket без протоколу поверх нього — це переизобретення велосипеда. Мінімум: визначити формат повідомлень, heartbeat-механізм, reconnection стратегію, чергу невідправлених повідомлень при втраті з'єднання.
На практиці для продуктових чатів використовуємо одне з трьох рішень:
Готовий чат SDK — SendBird, Stream Chat, Cometchat. Дають UI-компоненти, серверну інфраструктуру, push-сповіщення, модерацію. Швидко, надійно, але vendor lock-in та recurring costs.
Firebase Realtime Database / Firestore — для простих чатів без вимог до масштабуємості >100K concurrent users. Realtime Database зручніше для чату (впорядковані списки повідомлень), Firestore — для більш структурованих даних. Обмеження: немає вбудованого typing indicators та presence — реалізується окремо через onDisconnect().
Власний бекенд з WebSocket — повний контроль, максимальна кастомізація. Технічний стек: WebSocket через socket.io (Node.js) або Phoenix Channels (Elixir) + PostgreSQL + Redis для pub/sub. На мобілі: Starscream (iOS Swift), OkHttp WebSocket (Android), socket_io_client (Flutter).
Офлайн-режим — найтрудозатратніша частина. Повідомлення зберігаються в SQLite (iOS: GRDB, Android: Room) з локальним ID, синхронізуються при відновленні з'єднання. Конфлікти при одночасній відправці розв'язуються через vector clock або server-timestamp ordering.
VoIP: CallKit, ConnectionService та WebRTC
VoIP у мобільному додатку — це два різних сценарії: виглядати як телефонний дзвінок (системний дзвінок UI) або просто аудіо/відео дзвінок всередину додатку.
CallKit (iOS) дозволяє інтегрувати VoIP-дзвінок у системний інтерфейс: додаток з'являється на Lock Screen як звичайний дзвінок, працює з Bluetooth-гарнітурами, переривує інше аудіо. Реалізується через CXProvider + CXCallController. Плюс: додаток запускається через VoIP push (PKPushKit) навіть коли убито — обов'язково для отримання вхідних дзвінків.
На Android аналог — ConnectionService API. Складніша інтеграція, поведінка варіюється між виробниками (Xiaomi, Samsung з їх battery optimization агресивно убивають фонові процеси).
WebRTC — транспортний протокол для peer-to-peer медіа. WebRTC на iOS через GoogleWebRTC pod або нативний RTCPeerConnection. На Flutter — flutter_webrtc. Сигнальний сервер (обмін SDP, ICE candidates) — звичайно через той же WebSocket канал що й чат.
STUN/TURN сервери — обов'язкова інфраструктура. Без TURN ~15-20% користувачів за симетричним NAT не зможуть встановити P2P з'єднання. coturn — open source TURN сервер, Twilio NTS та Metered TURN — managed варіанти.
Лента та реакції
Бесконечна лента — UICollectionView з UICollectionViewDiffableDataSource на iOS, LazyColumn з Paging 3 на Android. Pagination через cursor-based підхід (не offset) — при вставці нових елементів курсор не зміщується, offset — зміщується, користувач бачить дублюючийся контент.
Реакції (емодзі на повідомлення) — технічно: кожна реакція — окрема запис у БД (message_id, user_id, emoji). Агрегація на сервері: GROUP BY emoji. WebSocket-событіє reaction_added оновлює лічильник в реальному часі. Анімація появи реакції — через withSpring (Reanimated) або Core Animation spring на iOS.
Push-сповіщення для соціальних событій: @mention, відповідь на коментар, новий підписник — все через APNs (iOS) та FCM (Android). Для rich notifications (з превю медіа) на iOS — Notification Service Extension, який завантажує медіа до показу.
| Функція | Готовий SDK | Кастомна реалізація |
|---|---|---|
| Базовий чат | SendBird, Stream | WebSocket + Room/GRDB |
| VoIP | Twilio, Agora | WebRTC + CallKit |
| Лента | — | Paging 3 / DiffableDataSource |
| Push для соц. событій | Firebase FCM/APNs | APNs direct |
Строки: базовий чат з історією та push — 4-6 тижнів. VoIP дзвінки з CallKit/ConnectionService — 3-5 тижнів. Повнофункціональна соціальна лента з реакціями, коментариями та сповіщеннями — від 3 місяців.







