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

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

- Human documentation: [https://docs.univer.ai/ru-RU/server/collaboration/browser-integration](https://docs.univer.ai/ru-RU/server/collaboration/browser-integration)

- Agent Markdown: [https://docs.univer.ai/ru-RU/server/collaboration/browser-integration.md](https://docs.univer.ai/ru-RU/server/collaboration/browser-integration.md)

- Requested language: `ru-RU`

- Content language: `ru-RU`

- Documentation version: `1.2.0`

- Source: [collaboration/browser-integration.ru-RU.mdx](https://github.com/dream-num/documentation/blob/dev/content/server/collaboration/browser-integration.ru-RU.mdx)

---

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

Подготовьте сервер по руководству [Интеграция сервера](https://docs.univer.ai/ru-RU/server.md), затем настройте редактор и загрузку ниже. Рассматривайте Server и Web из [Быстрого старта Office](https://docs.univer.ai/ru-RU/server/collaboration/quick-start.md) вместе.

```mermaid
flowchart LR; A["Редактор пользователя A"] <-->|Обмен изменениями| S["Совместный сервис"]; S <-->|Обмен изменениями| B["Редактор пользователя B"]; S --> D[("Сохранение документов")];
```

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

Сохраните ваш редактор Web SDK. По [настройке браузера в быстром старте](https://docs.univer.ai/ru-RU/server/collaboration/quick-start.md) добавьте плагины совместного редактирования и адреса загрузки документов, отправки изменений и WebSocket. Поддерживайте совместимые версии браузерных и серверных пакетов.

Фиксированные пользователи и права примера предназначены для демонстрации. В приложении передавайте учётные данные в запросах, чтобы сервер проверял личность и доступ к документу. Лицензирование описано в [настройке лицензии](https://docs.univer.ai/ru-RU/server/license.md).

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

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

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

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

Задайте текущего пользователя до загрузки документа. Он определяет личность участника и владельца локального офлайн-кэша; см. [Идентификация и авторизация](https://docs.univer.ai/ru-RU/server/collaboration/identity-and-authorization.md).

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

```ts
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](https://docs.univer.ai/ru-RU/guides/sheets/features/collaboration.md), [Docs](https://docs.univer.ai/ru-RU/guides/docs/features/collaboration.md), [Slides](https://docs.univer.ai/ru-RU/guides/slides/features/collaboration.md), [Boards](https://docs.univer.ai/ru-RU/guides/boards/features/collaboration.md), [Bases](https://docs.univer.ai/ru-RU/guides/bases/features/collaboration.md) и [PDFs](https://docs.univer.ai/ru-RU/guides/pdfs/features/collaboration.md). Проверьте поддержку в продукте и целевом серверном выпуске.

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

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

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

Если загрузка работает, а синхронизация нет, проверьте WebSocket. Если после перезапуска содержимое исчезает, проверьте серверное хранилище. Настройки описаны в [интеграции сервера](https://docs.univer.ai/ru-RU/server.md).

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

Для совместного редактирования импортированного файла создайте документ из преобразованных данных; см. [Интеграция обмена файлами](https://docs.univer.ai/ru-RU/server/import-export.md). Комментарии и история требуют собственных плагинов, сервисов и прав. Следуйте разделу [Модули расширений Office](https://docs.univer.ai/ru-RU/server/collaboration/extensions.md).

Настройка панелей истории описана в [Sheets](https://docs.univer.ai/ru-RU/guides/sheets/features/edit-history.md), [Docs](https://docs.univer.ai/ru-RU/guides/docs/features/edit-history.md), [Slides](https://docs.univer.ai/ru-RU/guides/slides/features/edit-history.md), [Boards](https://docs.univer.ai/ru-RU/guides/boards/features/edit-history.md) и [Bases](https://docs.univer.ai/ru-RU/guides/bases/features/edit-history.md). Текущие возможности PDFs см. в [Истории PDFs](https://docs.univer.ai/ru-RU/guides/pdfs/features/edit-history.md).

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

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

```ts
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`. Запрос отправки использует тот же тайм-аут подтверждения. Неподтверждённые изменения отправляются повторно с экспоненциальным увеличением интервала до максимума. Равные два тайм-аута дают постоянный интервал.

```ts
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` дают подробности.

```ts
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` в существующей инициализации и обработайте событие:

#### Режим плагинов

```ts
import { UniverCollaborationClientUIPlugin } from '@univerjs-pro/collaboration-client-ui'

univer.registerPlugin(UniverCollaborationClientUIPlugin, { enableDefaultConflictUI: false })
```

#### Пресет Sheets

```ts
import { UniverSheetsCollaborationPreset } from '@univerjs/preset-sheets-collaboration'

const collaborationPreset = UniverSheetsCollaborationPreset({ enableDefaultConflictUI: false })
```

#### Пресет Docs

```ts
import { UniverDocsCollaborationPreset } from '@univerjs/preset-docs-collaboration'

const collaborationPreset = UniverDocsCollaborationPreset({ enableDefaultConflictUI: false })
```

Добавьте пресет совместной работы к пресету редактора в существующем `createUniver({ presets: [...] })`, сохранив endpoints и историю. См. [параметры событий](https://docs.univer.ai/ru-RU/reference/facade/events.md#collaborationconflict) и [конфигурацию клиента](https://docs.univer.ai/ru-RU/reference/packages/plugins/univerjs-pro/collaboration-client.md).
