Разработка чата в мобильном приложении (один на один)

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Разработка чата в мобильном приложении (один на один)
Средняя
~5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    874
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Разработка чата в мобильном приложении (один на один)

Приватный чат между двумя пользователями — не «просто список сообщений». Здесь проблема обычно не в отображении, а в синхронизации состояний: пользователь на iOS отправил сообщение, Android-собеседник его видит через 3 секунды с дублем, потому что WebSocket отвалился и клиент переотправил через REST. Или история не загружается при плохом соединении, потому что пагинация реализована через OFFSET и timeout бьёт по 500-й странице.

Транспорт: WebSocket или SSE

Для чата один на один достаточно WebSocket-соединения. На iOS — URLSessionWebSocketTask (нативно, без зависимостей) или Starscream если нужна более гибкая обработка heartbeat. На Android — OkHttp WebSocket из коробки через Retrofit-экосистему или Ktor WebSocket Client для Kotlin Multiplatform.

Критичный момент — реконнект. WebSocket рвётся при смене сети (Wi-Fi → 4G), при блокировке фона iOS, при агрессивном Doze Mode на Android. Нужен exponential backoff: первый реконнект через 1s, затем 2s, 4s, 8s, cap 30s. После реконнекта — запрос missed messages с last_message_id чтобы не пропустить то, что пришло пока соединение было разорвано.

Firebase Realtime Database или Firestore — альтернатива собственному WS-серверу для небольших проектов. Быстро стартовать, но при сложной бизнес-логике (модерация, шифрование на уровне сервера) возникает ограничение Cloud Functions.

Как мы строим чат

Модель данных

Сообщение: id, conversation_id, sender_id, body, type (text/image/file/system), status (sent/delivered/read), client_message_id (UUID генерируется на клиенте), created_at. client_message_id — ключ идемпотентности: если клиент переотправляет после таймаута, сервер не создаёт дубль.

Conversation: id, participant_ids[], last_message_id, last_message_at. Индекс: (participant_ids, last_message_at DESC) — чтобы список диалогов у пользователя выбирался быстро.

Пагинация истории

Cursor-based по (created_at, id): загружаем последние N сообщений, при скролле вверх передаём before_cursor. Это работает стабильно при быстрой вставке новых сообщений — OFFSET «плывёт», когда между страницами появляются новые записи.

На iOS список сообщений — UICollectionView с инвертированным layout (новые снизу): transform = CGAffineTransform(scaleX: 1, y: -1) на collectionView и каждой ячейке. При добавлении нового сообщения insertItems с scrollToItem — без reloadData который вызывает мерцание. На Android — LazyColumn(reverseLayout = true) в Jetpack Compose.

Статусы доставки и прочтения

Delivered: сервер подтверждает получение сообщения (ack в WS-протоколе) и обновляет статус. Read: клиент-получатель отправляет read receipt когда conversation открыта и сообщение видимо на экране (через Intersection Observer на вебе или через UICollectionView.indexPathsForVisibleItems на iOS).

Статусы в UI: одна галочка (sent), две серых (delivered), две синих (read) — классика. Меняем через локальный update в DiffableDataSource без сетевого запроса.

Шифрование

Для базового end-to-end: Signal Protocol через libsignal-client (Rust-библиотека с биндингами для iOS/Android). Ключи хранятся в Keychain (iOS) / Android Keystore. Сервер видит только зашифрованный blob — даже при компрометации БД переписка не читается.

Если E2E не обязательно — шифрование на транспорте (TLS 1.3) + шифрование в покое на стороне сервера достаточно для большинства случаев.

Push-уведомления когда чат закрыт

FCM (Android) и APNs (iOS). На iOS нужен UNUserNotificationCenter + UNNotificationServiceExtension если нужно показать превью зашифрованного сообщения: Extension расшифровывает payload перед показом без передачи ключей серверу.

Deep link при тапе на пуш — открывает конкретный conversation: myapp://chat/conversation/{id}. Реализуется через UIApplicationDelegate.application(_:open:options:) или onOpenURL в SwiftUI.

Этапы и сроки

Базовый чат (WS-соединение, история с пагинацией, статусы, пуши) — 5 рабочих дней на одну платформу. Добавление медиа-вложений, E2E-шифрования, индикатора набора текста (typing indicator через WS-event) — ещё 3-5 дней. Flutter — немного быстрее за счёт единой кодовой базы. Стоимость — после анализа требований и целевых платформ.