Интеграция совместного редактирования
Подключение редактора Univer к совместному сервису для работы пользователей над одним документом.
Совместное редактирование подключает браузерные редакторы к сервису общих документов. Например, два пользователя открывают одну таблицу, и изменение в одном браузере появляется в другом.
Подготовьте сервер по руководству Интеграция сервера, затем настройте редактор и загрузку ниже. Рассматривайте Server и Web из Быстрого старта Office вместе.
Подключение существующего редактора
Сохраните ваш редактор Web SDK. По настройке браузера в быстром старте добавьте плагины совместного редактирования и адреса загрузки документов, отправки изменений и WebSocket. Поддерживайте совместимые версии браузерных и серверных пакетов.
Фиксированные пользователи и права примера предназначены для демонстрации. В приложении передавайте учётные данные в запросах, чтобы сервер проверял личность и доступ к документу. Лицензирование описано в настройке лицензии.
Создание и открытие одного документа
Создание и открытие — разные действия:
- При создании документа сервер сохраняет его и возвращает ID.
- Браузер загружает этот ID. Используйте его повторно при открытии или передаче другому пользователю.
Поле API unitId — это ID документа. Не создавайте новый пустой локальный документ при каждом посещении.
Задайте текущего пользователя до загрузки документа. Он определяет личность участника и владельца локального офлайн-кэша; см. Идентификация и авторизация.
Например, после регистрации Sheets и совместных плагинов загрузите серверную таблицу:
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 проверяется документ в фокусе. Наличие соединения не означает сохранение изменений.
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. Запрос отправки использует тот же тайм-аут подтверждения. Неподтверждённые изменения отправляются повторно с экспоненциальным увеличением интервала до максимума. Равные два тайм-аута дают постоянный интервал.
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 дают подробности.
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 в существующей инициализации и обработайте событие:
import { UniverCollaborationClientUIPlugin } from '@univerjs-pro/collaboration-client-ui'univer.registerPlugin(UniverCollaborationClientUIPlugin, { enableDefaultConflictUI: false })import { UniverSheetsCollaborationPreset } from '@univerjs/preset-sheets-collaboration'const collaborationPreset = UniverSheetsCollaborationPreset({ enableDefaultConflictUI: false })import { UniverDocsCollaborationPreset } from '@univerjs/preset-docs-collaboration'const collaborationPreset = UniverDocsCollaborationPreset({ enableDefaultConflictUI: false })Добавьте пресет совместной работы к пресету редактора в существующем createUniver({ presets: [...] }), сохранив endpoints и историю. См. параметры событий и конфигурацию клиента.
Насколько полезно это руководство?