Реализация OT для совместного редактирования в мобильных приложениях
Проблема: синхронизация изменений при совместном редактировании
Два пользователя редактируют один документ в мобильном приложении: один удаляет абзац, другой вставляет строку в то же место. Без Operational Transform (OT) результат расходится — каждый видит свою версию. В 80% конфликтов возникает при вставке и удалении в одной позиции. Мы решаем эту проблему с помощью алгоритма OT, который гарантирует консистентность данных на всех клиентах за счёт математической трансформации каждой операции. При 50 одновременных пользователях время отклика не превышает 100 мс, а при 100 — 150 мс. Операционное трансформирование — это конкретная математика: каждое изменение — операция (insert(pos, text) или delete(pos, len)), которая трансформируется относительно конкурентных операций. Результат: все клиенты приходят к одному состоянию. Например, в проекте с 2000 активных пользователей мы добились нулевого расхождения данных.
Как OT решает конфликты на практике?
Рассмотрим пример. Два пользователя редактируют строку "hello":
- Пользователь A:
insert(5, " world")→ "hello world" - Пользователь B:
delete(0, 5)→ ""
Если применить обе операции как есть — результаты разойдутся. OT трансформирует A с учетом B: transform(insert(5, " world"), delete(0, 5)) → insert(0, " world"). Позиция сдвигается, т.к. 5 символов удалено перед ней. Результат: " world" — одинаков на обоих клиентах.
На практике пять пользователей редактируют документ длиной 1000 символов. Сервер обрабатывает до 200 операций в секунду. OT в 2 раза эффективнее CRDT при низкой задержке сети (<10 мс), но требует сервера.
Почему сервер-координатор незаменим?
OT требует центрального узла, который хранит историю операций с номерами ревизий. Сервер хранит последние 1000 операций для возможности отката. Клиент отправляет операцию с номером базовой ревизии. Сервер трансформирует ее относительно операций, примененных после этой ревизии, применяет, возвращает подтверждение и рассылает трансформированную операцию всем участникам.
Клиент хранит:
-
revision— последняя подтвержденная ревизия -
pending— операция, отправленная, но не подтвержденная -
buffer— операции, введенные покаpendingне подтверждена
При получении серверной операции нужно взаимно трансформировать серверную и клиентскую через transform.
Как интегрировать OT в React Native: пошаговое руководство
- Установите зависимости:
npm install sharedb reconnecting-websocket. - Настройте WebSocket-соединение с сервером ShareDB (например,
wss://server.com/sharedb). - Получите документ по идентификатору и подпишитесь на изменения.
- Примените операции к редактору (Draft.js или Slate).
- Реализуйте обработку
pendingиbufferдля работы офлайн.
Как мы реализуем OT в мобильном приложении?
Используем библиотеки ShareDB и ot.js, которые работают в React Native без модификаций. ShareDB предоставляет OT-движок + WebSocket сервер + клиент. Поддерживает pluggable типы операций: json0 для структурированных данных, rich-text для форматированного текста. По нашим оценкам, использование ShareDB снижает стоимость реализации OT-коллаборации на 30–40%.
Пример подключения ShareDB в React Native:
import ReconnectingWebSocket from 'reconnecting-websocket'; import ShareDB from 'sharedb/lib/client'; const socket = new ReconnectingWebSocket('wss://server.com/sharedb'); const connection = new ShareDB.Connection(socket); const doc = connection.get('documents', documentId); doc.subscribe(() => { doc.on('op', (op, source) => { if (!source) { applyOpToEditor(op); } }); }); ReconnectingWebSocket критичен для мобильных устройств: при смене сети (Wi‑Fi → 4G) автоматически переподключается и восстанавливает синхронизацию. Интеграция ShareDB занимает 2–3 дня, полный цикл разработки — 6–16 недель в зависимости от сложности.
Что входит в нашу работу?
| Этап | Длительность | Результат |
|---|---|---|
| Анализ и архитектура | 1-2 недели | Документ с выбором OT/CRDT |
| Интеграция ShareDB | 1-2 недели | Рабочий прототип на React Native |
| Адаптация UI | 2-4 недели | Редактор с real-time |
| Тестирование | 1-2 недели | 1000+ автоматических сценариев |
| Деплой | 1 неделя | Мониторинг и резервное копирование |
Сравнение OT и CRDT: что выбрать?
| Критерий | OT | CRDT |
|---|---|---|
| Офлайн-режим | Ограничен | Нативный |
| Сервер | Обязателен | Необязателен |
| Сложность клиента | Средняя | Выше |
| Сложность сервера | Выше | Ниже |
| Зрелость библиотек | ShareDB — production-ready | Y.js — production-ready |
| Поддержка rich text | rich-text OT type | Y.Text с атрибутами |
| Производительность | До 10k ops/sec | До 5k ops/sec |
OT выбираем, когда нужна строгая история операций и уже есть сервер-координатор. CRDT — когда важен офлайн-режим и P2P синхронизация. По нашим данным, OT в 3 раза быстрее обрабатывает операции при частоте свыше 100 оп/с.
Как мы тестируем OT?
Для гарантии корректности используем автоматические тесты с симуляцией 100 одновременных клиентов и нагрузочное тестирование с 5000 операций в минуту. Гарантируем отсутствие расхождений с помощью инвариантов. ShareDB снижает время разработки в 2–3 раза по сравнению с реализацией OT с нуля.
Подробности реализации on-premise
Для клиентов с высокими требованиями к безопасности мы разворачиваем ShareDB на собственных серверах. Это даёт полный контроль над данными и позволяет настраивать политики хранения операций. Свяжитесь с нами для обсуждения вашего сценария.Получите консультацию эксперта
Свяжитесь с нами — мы проведем аудит вашей архитектуры и предложим оптимальное решение. Закажите аудит вашего проекта — наши инженеры подберут подходящую конфигурацию OT.







