Совместное редактирование в реальном времени - как это работает?

Я пишу приложение, в котором я хотел бы иметь возможности совместного редактирования документов в режиме реального времени (очень похоже на редактирование в стиле Документов Google).

Я знаю, как отслеживать положение курсора, это просто. Просто опрашивайте сервер каждые полсекунды или секунды с текущим идентификатором пользователя, именем файла, номером строки и номером строки, которые могут быть сохранены в базе данных, и возвращаемое значение этого запроса опроса является позицией курсоров другого пользователя.

Что я не знаю, как это сделать, так это обновить документ таким образом, чтобы он не отбрасывал курсор и не вызывал полную перезагрузку, поскольку это было бы слишком медленным для моих целей.

Это действительно должно работать только в Google Chrome, предпочтительно Firefox. Мне не нужно поддерживать любой другой браузер.

7 ответов

Решение

Алгоритм, используемый за кулисами для объединения совместных изменений от нескольких пиров, называется операционным преобразованием. Это не тривиально для реализации, хотя.

Смотрите также этот вопрос для полезных ссылок.

Совместное редактирование в реальном времени требует нескольких вещей, чтобы быть эффективным. Большинство других ответов здесь сосредоточены только на одном аспекте проблемы; а именно распределенное состояние (он же shared-mutable-state). Операционное преобразование (OT), бесконфликтные реплицируемые типы данных (CRDT), дифференциальная синхронизация и другие связанные технологии - все это подходы к достижению распределенного состояния почти в реальном времени. Большинство фокусируется на возможной согласованности, которая допускает временные расхождения каждого из состояний участников, но гарантирует, что каждое состояние участников будет в конечном итоге сходиться при прекращении редактирования. Другие ответы упоминали несколько реализаций этих технологий.

Однако после того, как вы поделились изменяемым состоянием, вам потребуется несколько других функций, чтобы обеспечить разумный пользовательский опыт. Примеры этих дополнительных концепций включают в себя:

  • Идентичность: кто те люди, с которыми вы сотрудничаете.
  • Присутствие: Кто сейчас "здесь" редактирует с вами сейчас.
  • Общение: чат, аудио, видео и т. Д., Которые позволяют пользователям координировать действия
  • Совместная реплика: функции, которые дают указания относительно того, что другие участники делают и / или собираются сделать.

Общие курсоры и выборки являются примерами Collaborative Cueing (также известной как Collaboration Awareness). Они помогают пользователям понять намерения и вероятные последующие действия других участников. Оригинальный плакат частично спрашивал о взаимодействии между общим изменяемым состоянием и совместной репликой. Это важно, потому что расположение курсора или выделения в документе обычно описывается через местоположения в документе. Проблема в том, что расположение курсора (например) зависит от контекста документа. Когда я говорю, что мой курсор находится в индексе 37, это означает символ 37 в документе, на который я смотрю. Документ, который вы можете иметь прямо сейчас, может отличаться от моего из-за ваших правок или изменений других пользователей, и поэтому индекс 37 в вашем документе может быть неверным.

Таким образом, механизм, который вы используете для распределения местоположений курсора, должен каким-то образом быть интегрирован в механизм системы или, по крайней мере, знать о нем, который обеспечивает управление параллелизмом общего изменяемого состояния. Сегодня одной из проблем является то, что, хотя существует множество OT / CRDT, двунаправленных сообщений, чатов и других библиотек, они представляют собой изолированные решения, которые не являются интегрированными. Это затрудняет создание системы конечного пользователя, которая обеспечивает хороший пользовательский опыт и часто приводит к техническим трудностям, оставленным на усмотрение разработчика.

В конечном счете, чтобы реализовать эффективную систему совместного редактирования в реальном времени, вам необходимо рассмотреть все эти аспекты; и мы даже не обсуждали историю, авторизацию, разрешение конфликтов на уровне приложений и многие другие аспекты. Вы должны создать или найти технологии, которые поддерживают каждую из этих концепций таким образом, чтобы иметь смысл для вашего варианта использования. Тогда вы должны интегрировать их.

Хорошей новостью является то, что приложения, поддерживающие совместное редактирование, становятся все более популярными. Технологии, которые поддерживают их создание, становятся зрелыми, и новые становятся доступными каждый месяц. Firebase было одним из первых решений, которое попыталось объединить многие из этих концепций в простой в использовании API. Конвергенция новичков (полное раскрытие, я являюсь основателем Convergence Labs) предоставляет универсальный API-интерфейс, который поддерживает большинство этих аспектов совместного редактирования и может значительно сократить время, стоимость и сложность построения реального времени. приложения для совместного редактирования.

Вам не нужно xmpp или wave для этого обязательно. Большая часть работы над реализацией с открытым исходным кодом под названием infinote уже была проделана с помощью jinfinote ( https://github.com/sveith/jinfinote). Jinfinote недавно также был портирован на python ( https://github.com/phrearch/py-infinote) для централизованной обработки параллелизма и состояния документа. В настоящее время я использую оба в проекте hwios ( https://github.com/phrearch/hwios), который опирается на веб-сокеты и транспорт json. Вы действительно не хотите использовать опрос для такого рода приложений. Кроме того, xmpp, кажется, усложняет вещи излишне IMO.

После того, как я наткнулся на этот вопрос и провел более тщательный поиск, я думаю, что лучшим автономным приложением, которое стоит проверить, будет Etherpad, который работает как браузерное приложение JS и использует Node.js на стороне сервера. Технология, которая стоит за этим, известна как операционная трансформация.

Etherpad изначально был довольно тяжеловесным приложением, которое было куплено Google и встроено в Google Wave, но оно не получилось. Код был выпущен как открытый исходный код, а технология была переписана на Javascript для Etherpad Lite, теперь переименованной просто в "Etherpad". Некоторые из технологий Etherpad, вероятно, также были включены в Google Docs.

Начиная с Etherpad, для этой технологии существовали различные версии, в частности, некоторые библиотеки Javascript, которые позволяют интегрировать ее непосредственно в ваше веб-приложение:

Я поддерживаю пакет meteor-sharejs для добавления редакторов в реальном времени непосредственно в приложение Meteor, которое, по моему мнению, является лучшим из двух миров:)

Как указал Гинтаутас, это делается Оперативным Преобразованием. Насколько я понимаю, основная часть исследований и разработок по этой функции была выполнена в рамках ныне несуществующего проекта Google Wave и известна как Wave Protocol. К счастью, Google Wave имеет открытый исходный код, поэтому вы можете получить несколько хороших примеров кода по адресу http://code.google.com/p/wave-protocol/

Команда Google Docs провела небольшое исследование о том, как работает сотрудничество в реальном времени, но я не могу найти запись в блоге.

Тем не менее, на странице Википедии есть кое-что достойное: http://en.wikipedia.org/wiki/Collaborative_real-time_editor

Недавно я опубликовал репозиторий с рабочим примером того, чего вы пытаетесь достичь:

https://quill-sharedb-cursors.herokuapp.com/

Он основан на ShareDB (OT), работающем в качестве внешнего интерфейса и редактора форматированного текста Quill на внешнем интерфейсе.

По сути, просто связываю все эти вещи с еще большим кодом для рисования курсоров. Код должен быть достаточно простым для понимания и копирования в любое конкретное решение.

Надеюсь, это поможет с усилием.

Другие вопросы по тегам