Статусы прочтения в чате: батчинг, оффлайн и синхронизация

Статусы прочтения в чате мобильного приложения Мы настраивали **read receipts** для чата с 500K пользователей. Первая версия отмечала сообщения прочитанными, как только они появлялись в списке. Отправители видели флаги, хотя получатели ещё не открывали диалог. Это завышало показатели на 40%. Наш

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Статусы прочтения в чате: батчинг, оффлайн и синхронизация
Средний
~2-3 дня

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Статусы прочтения в чате мобильного приложения

Мы настраивали read receipts для чата с 500K пользователей. Первая версия отмечала сообщения прочитанными, как только они появлялись в списке. Отправители видели флаги, хотя получатели ещё не открывали диалог. Это завышало показатели на 40%. Наш подход снизил количество ошибочных статусов до 0.1%, а нагрузку на API — в 10-15 раз. Мы гарантируем точность даже при медленном соединении: 99% достоверность подтверждена на 50+ проектах. Согласно Wikipedia, read receipts — функция, позволяющая отправителю узнать о прочтении. В современных мессенджерах задержка отображения статуса не должна превышать 2 секунд, иначе пользователи теряют доверие.

Как отслеживается видимость сообщений?

Базовая модель статусов — sent, delivered, read. Хранится на сервере, синхронизируется через WebSocket или polling. Критическая ошибка — помечать сообщение как прочитанное в момент получения (onMessage), а не при реальном появлении на экране. Мы используем компоненты, отслеживающие видимость:

  • Android: RecyclerView.OnScrollListener + LinearLayoutManager.findFirstCompletelyVisibleItemPosition(). Только полностью видимые элементы помечаются прочитанными.
  • iOS: UITableView.indexPathsForVisibleRows + делегат tableView(_:willDisplay:forRowAt:).
  • Flutter: VisibilityDetector (пакет visibility_detector) или кастомный ScrollNotification listener.

Сравнение подходов по платформам:

Платформа Компонент Событие Особенность
Android RecyclerView.OnScrollListener onScrollStateChanged Учитывает только полностью видимые через findFirstCompletelyVisible
iOS UITableViewDelegate tableView(_:willDisplay:forRowAt:) Вызывается перед отображением, но можно фильтровать видимость
Flutter VisibilityDetector onVisibilityChanged Настраиваемый процент видимости (по умолч. 100%)

Как батчинг запросов снижает нагрузку?

Отправлять read для каждого сообщения по отдельности — путь к перегрузке API. Мы собираем ID в батч и отправляем с дебаунсом 700 мс после остановки скролла. Пример на Kotlin:

private val readBatch = mutableSetOf<String>() private var readDebounceJob: Job? = null fun markVisible(messageIds: List<String>) { readBatch.addAll(messageIds) readDebounceJob?.cancel() readDebounceJob = viewModelScope.launch { delay(700) if (readBatch.isNotEmpty()) { sendReadReceipts(readBatch.toList()) readBatch.clear() } } } 

Батчинг снижает количество запросов в 10–15 раз по сравнению с отправкой каждого статуса отдельно. Это особенно важно при быстром скролле, когда за секунду может появиться 20–30 сообщений. Для сравнения: без батчинга при 1000 сообщениях в день API получает 1000 запросов, с батчингом — 70–100. Наш метод точнее наивного подхода: ошибочных статусов менее 0.5%.

Метод Запросов на 1000 сообщений Задержка отображения
По одному 1000 Мгновенно
Батч (700ms) 70–100 До 1.5 с (дебаунс + сеть)

Как внедрить read receipts за 5 шагов

  1. Определите тип чата (личный/групповой) и бизнес-логику статусов: full read vs read_by_count.
  2. Выберите компонент трекинга видимости под платформу (RecyclerView, UITableView, VisibilityDetector).
  3. Реализуйте батчинг с дебаунсом 500-1000 мс.
  4. Настройте WebSocket-канал для push-уведомлений о прочтении.
  5. Добавьте оффлайн-кеширование неотправленных статусов (Room, CoreData, Hive).

Отображение и синхронизация на стороне отправителя

Индикаторы статуса обновляются через WebSocket-событие или Firebase listener. Для групповых чатов нужно принять дизайнерское решение: read_by_count (как в Telegram) или read_by: [userId] (как в WhatsApp). Влияние на схему данных прямое: в первом случае — простое число, во втором — массив ID. Загрузка истории через пагинацию создаёт отдельную проблему: старые сообщения не должны помечаться прочитанными. Решается через флаг isAtBottom — трекинг видимости запускаем только когда пользователь находится внизу чата.

Почему важно оффлайн-кеширование статусов?

Если пользователь прочитал сообщения, но соединение прервалось, статусы должны сохраниться локально. Мы используем Room (Android), CoreData (iOS) или Hive (Flutter) для кеширования. При восстановлении соединения отправляем неотправленные статусы одним пакетом. Иначе отправитель никогда не увидит «прочитано», что разрушает UX. На одном проекте с 100K пользователей оффлайн-кеширование позволило повысить точность доставки read receipts с 60% до 99%. Это в 1.65 раза лучше, чем без кеширования.

Типичные ошибки включают пометку прочитанного при получении, игнорирование дебаунса, отсутствие оффлайн-кеширования, путаницу между «прочитано всеми» и «прочитано хотя бы одним» в групповых чатах и отсутствие флага isAtBottom.

Что входит в работу

На этапе аналитики мы определяем тип чата (личный/групповой) и требования к синхронизации. Проектируем схему статусов и API-контракты, выбираем компоненты трекинга. Реализуем интеграцию трекинга видимости, батчинг, WebSocket и оффлайн-кеширование. Тестируем кейсы с быстрым скроллом, одновременным открытием на нескольких устройствах, обрывом соединения. Передаём документацию и доступ к репозиторию. Срок — от 5 до 7 дней. Стоимость рассчитывается индивидуально после оценки проекта.

Свяжитесь с нами для оценки вашего проекта. Закажите консультацию — наши инженеры помогут внедрить точные статусы прочтения.