Интеграция совместного редактирования

Подключение редактора Univer к совместному сервису для работы пользователей над одним документом.

Совместное редактирование подключает браузерные редакторы к сервису общих документов. Например, два пользователя открывают одну таблицу, и изменение в одном браузере появляется в другом.

Подготовьте сервер по руководству Интеграция сервера, затем настройте редактор и загрузку ниже. Рассматривайте Server и Web из Быстрого старта Office вместе.

100%

Подключение существующего редактора

Сохраните ваш редактор Web SDK. По настройке браузера в быстром старте добавьте плагины совместного редактирования и адреса загрузки документов, отправки изменений и WebSocket. Поддерживайте совместимые версии браузерных и серверных пакетов.

Фиксированные пользователи и права примера предназначены для демонстрации. В приложении передавайте учётные данные в запросах, чтобы сервер проверял личность и доступ к документу. Лицензирование описано в настройке лицензии.

Создание и открытие одного документа

Создание и открытие — разные действия:

  1. При создании документа сервер сохраняет его и возвращает ID.
  2. Браузер загружает этот ID. Используйте его повторно при открытии или передаче другому пользователю.

Поле API unitId — это ID документа. Не создавайте новый пустой локальный документ при каждом посещении.

Задайте текущего пользователя до загрузки документа. Он определяет личность участника и владельца локального офлайн-кэша; см. Идентификация и авторизация.

Например, после регистрации Sheets и совместных плагинов загрузите серверную таблицу:

TypeScript
import { UserManagerService } from '@univerjs/core'import '@univerjs-pro/collaboration-client/facade'univer.__getInjector().get(UserManagerService).setCurrentUser({ userID, name, avatar })const workbook = await univerAPI.getCollaboration().loadSheetAsync('your-document-id')if (!workbook) throw new Error('Document could not be loaded')

Способы загрузки для продуктов описаны в Sheets, Docs, Slides, Boards, Bases и PDFs. Проверьте поддержку в продукте и целевом серверном выпуске.

Проверка синхронизации, сохранения и прав

Откройте один документ в двух независимых сеансах, например обычном и приватном окне. Измените его в одном и проверьте второй. Затем проверьте содержимое после обновления, переподключения и перезапуска сервера.

Тестируйте редактора, читателя и пользователя без доступа. Режим только для чтения в UI управляет взаимодействиями страницы, но сервер всё равно должен отклонять неавторизованные чтения и изменения.

Если загрузка работает, а синхронизация нет, проверьте WebSocket. Если после перезапуска содержимое исчезает, проверьте серверное хранилище. Настройки описаны в интеграции сервера.

Добавление обмена файлами, комментариев или истории

Для совместного редактирования импортированного файла создайте документ из преобразованных данных; см. Интеграция обмена файлами. Комментарии и история требуют собственных плагинов, сервисов и прав. Следуйте разделу Модули расширений Office.

Настройка панелей истории описана в Sheets, Docs, Slides, Boards и Bases. Текущие возможности PDFs см. в Истории PDFs.

Состояние синхронизации и повторные отправки

После импорта Facade событие CollaborationStatusChanged сообщает текущее состояние уже совместно редактируемых документов при регистрации, затем изменения без последовательных повторов состояния. hasWritePending(unitId) учитывает ожидающие отправки, подтверждения и офлайн-изменения. Без ID проверяется документ в фокусе. Наличие соединения не означает сохранение изменений.

TypeScript
import '@univerjs-pro/collaboration-client/facade'const collaboration = univerAPI.getCollaboration()const statusSubscription = univerAPI.addEvent(univerAPI.Event.CollaborationStatusChanged, (event) => {  console.info(event.unitId, event.status, collaboration.hasWritePending(event.unitId))})const resendSubscription = univerAPI.addEvent(univerAPI.Event.CollaborationChangesetResend, (event) => {  console.info(event.unitId, event.reason, event.attempt, event.unsyncedMutationCount, event.nextDelayMs)})

CollaborationChangesetResend вызывается при повторной отправке, не первой. Причины: ack_timeout, should_retry, reconnect. Поля attempt, elapsedMs, unsyncedMutationCount, nextDelayMs подходят для индикатора сохранения и повторов. При удалении редактора освобождайте подписки.

Задержка объединения и тайм-аут подтверждения различаются. По умолчанию в миллисекундах: sendChangesetTimeout: 2000, changesetAckTimeout: 20000, maxChangesetAckTimeout: 120000. Запрос отправки использует тот же тайм-аут подтверждения. Неподтверждённые изменения отправляются повторно с экспоненциальным увеличением интервала до максимума. Равные два тайм-аута дают постоянный интервал.

TypeScript
import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client'import { BrowserCollaborationSocketService } from '@univerjs-pro/collaboration-client-ui'univer.registerPlugin(UniverCollaborationClientPlugin, {  socketService: BrowserCollaborationSocketService,  sendChangesetTimeout: 200,  changesetAckTimeout: 20_000,  maxChangesetAckTimeout: 120_000,})

Добавьте параметры в существующую регистрацию клиента, сохранив socket и endpoints. Пресеты совместной работы Sheets и Docs используют задержку объединения 200 мс и не предоставляют настройки тайм-аута подтверждения; для них используйте режим плагинов.

Обработка конфликтов приложением

CollaborationConflict вызывается один раз при входе в конфликт после попытки очистить офлайн-кеш. Подпишитесь до загрузки документов. reason: transform_failed, apply_failed, changeset_rejected, permission_rejected или remote_revert; при наличии message и revert дают подробности.

TypeScript
import type { IEventParamConfig } from '@univerjs/core/facade'import '@univerjs-pro/collaboration-client/facade'const conflicts = new Map<string, IEventParamConfig['CollaborationConflict']>()const conflictSubscription = univerAPI.addEvent(univerAPI.Event.CollaborationConflict, (event) => {  conflicts.set(event.unitId, event)})

Пример сохраняет событие для экрана восстановления. Map существует только в памяти: до перезагрузки сохраните или экспортируйте localChanges. Удержать данные нужно в этом событии: очищенный кеш затем не восстановить. awaitingChangeset мог уже примениться на сервере, поэтому не воспроизводите его без проверки.

При cacheCleared: false перезагрузка повторно применит старый кеш. Сначала решите проблему очистки. Очистка не означает сохранение несинхронизированных изменений. При permission_rejected также нужно восстановить доступ: перезагрузка не выдаёт права.

По умолчанию UI показывает уведомление с причиной и предлагает перезагрузку после успешной очистки либо повтор при ошибке очистки. Чтобы управлять восстановлением самостоятельно, задайте enableDefaultConflictUI: false в существующей инициализации и обработайте событие:

TypeScript
import { UniverCollaborationClientUIPlugin } from '@univerjs-pro/collaboration-client-ui'univer.registerPlugin(UniverCollaborationClientUIPlugin, { enableDefaultConflictUI: false })

Добавьте пресет совместной работы к пресету редактора в существующем createUniver({ presets: [...] }), сохранив endpoints и историю. См. параметры событий и конфигурацию клиента.

Насколько полезно это руководство?

© 2026 DreamNum Co., Ltd.