Многие из нас сталкивались с несколькими приложениями для совместной работы в реальном времени, которые помогают командам работать вместе над одним документом или проектом. Такие приложения, как Google Docs или Spreadsheets, позволяют пользователям редактировать документы одновременно.

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

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

Итак, если мы более подробно рассмотрим, как работают эти приложения для совместной работы в реальном времени, мы встретим такие термины, как OT (операционное преобразование) и CRDT (бесконфликтный реплицированный тип данных). .

Некоторые из вас могут задаться вопросом, что на самом деле означают эти слова. Далее следует, какой из них следует использовать для создания интерактивных приложений в реальном времени.

Итак, начнем с основ OT и CRDT.

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

Чтобы узнать больше о OT (операционное преобразование) и CRDT (бесконфликтный реплицированный тип данных), перейдите по этой ссылке.

Приложения для совместной работы могут вызвать расхождение, если нет синхронизации между клиентами при редактировании текста. Это может привести к множеству конфликтов в окончательных данных. Мы используем CRDT, чтобы избежать подобных проблем.

Есть много типов CRDT. Обратитесь к этой ссылке для хорошего обзора типов CRDT. В настоящее время реализовано множество фреймворков CRDT.

В этом руководстве давайте узнаем, как создать приложение для совместной работы в реальном времени с использованием CRDT в angular.

Примечание. В этом руководстве мы будем использовать модуль Yjs NPM в качестве инфраструктуры CRDT. Пользователи могут реализовать свой собственный дизайн текстового редактора. В этом руководстве мы используем Angular, чтобы реализовать то же самое.

Итак, приступим !!

Шаги по созданию приложения для совместной работы в реальном времени с использованием CRDT

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

  • Для начала создайте проект Angular и установите модуль npm для Yjs и y-WebSocket.
npm install yjs y-websocket
  • Теперь Yjs предоставляет нам несколько предопределенных привязок для совместного редактирования текста в реальном времени. Сначала мы покажем, как реализовать эту привязку и создать текстовый редактор в реальном времени. В более поздней части мы создадим приложение TODO в реальном времени с CRDT, используя Yjs с нуля.
  • Во-первых, мы будем использовать привязку code-mirror из Yjs для текстового редактора совместной работы в реальном времени без каких-либо конфликтов.
npm install codemirror
  • Чтобы добавить в интерфейс текстовый редактор, позволяющий пользователю редактировать текст, нам нужно добавить эти команды в файл машинописного текста. Это создаст текстовый редактор, в котором пользователи смогут сообщать свои мысли в режиме реального времени.
import { Component } from "@angular/core";
import * as Y from "yjs";
import CodeMirror from "codemirror";
import { WebsocketProvider } from "y-websocket";
import { CodemirrorBinding } from "y-codemirror";
export class YjsComponent {
// New Doc initialised
ydoc = new Y.Doc();
// Websocket Provider
provider = new WebsocketProvider(
"wss://demos.yjs.dev",
"codemirror-large",
this.ydoc
);
textContent = "Disconnect"
constructor() {
// Using Codemirror package from YJS for building connection between users
// Codemirror Code for setting up Textarea field for entering data
const yText = this.ydoc.getText("codemirror");
const editorContainer = document.createElement("div");
editorContainer.setAttribute("id", "editor");
document.body.insertBefore(editorContainer, null);
// Code for adding line numbers to the text editor.
const editor = CodeMirror(editorContainer, {
mode: "javascript",
lineNumbers: true,
});
const binding = new CodemirrorBinding(yText, editor, this.provider.awareness);
const provider = this.provider;
const ydoc = this.ydoc;
// @ts-ignore
window.example = { provider, ydoc, yText, binding, Y };
}
}
  • Теперь, чтобы подключить / отключить редактор от соединения WebSocket в реальном времени, нам нужно написать функцию.
// Function for connecting/disconnecting websocket connection between users.
connect() {
if (this.provider.shouldConnect) {
this.provider.disconnect();
this.textContent = "Connect";
} else {
this.provider.connect();
this.textContent = "Disconnect";
}
}
  • HTML-часть для добавления кнопки для подключения редактора к WebSocket-соединению в реальном времени будет выглядеть так.
<!-- Button for disconnecting/connecting connection between users-->
<button type="button" id="y-connect-btn" (click)="connect()">{{textContent}}</button>
  • Часть CSS для добавления курсора, чтобы определить, какой пользователь в настоящее время редактирует документ, приведена ниже. Рядом с курсором отобразится идентификатор пользователя.
.remote-caret.hide-name > div {
transition-delay: 0.7s;
opacity: 0;
}
.remote-caret:hover > div {
opacity: 1;
transition-delay: 0s;
}
.remote-caret {
position: absolute;
border-left: black;
border-left-style: solid;
border-left-width: 2px;
height: 1em;
}
.remote-caret > div {
position: relative;
top: -1.05em;
font-size: 13px;
background-color: rgb(250, 129, 0);
font-family: serif;
font-style: normal;
font-weight: normal;
line-height: normal;
user-select: none;
color: white;
padding-left: 2px;
padding-right: 2px;
z-index: 3;
transition: opacity 0.3s ease-in-out;
}

Ниже представлена ​​демонстрация совместной работы в реальном времени. Это отобразит идентификатор пользователя, который в настоящее время редактирует текст.

Теперь давайте посмотрим, как CRDT играет роль в предоставлении бесконфликтных данных. Для этого мы отключим ссылку на веб-сокет, обновим документ и посмотрим, как CRDT устранит споры и предоставит надежные данные, когда ссылка на веб-сокет снова будет включена.

На изображении выше вы увидите, что после включения соединения WebSocket в действие вступила CRDT, которая устранила все конфликты и предоставила согласованные данные.

Теперь давайте посмотрим, как с нуля создать приложение TODO в реальном времени, используя Yjs.

  • Ниже приведен код для создания списка Todo в реальном времени и устранения конфликтов с помощью CRDT.
import { Component, OnInit } from "@angular/core";
import * as Y from "yjs";
import { WebsocketProvider } from "y-websocket";
import { IndexeddbPersistence } from 'y-indexeddb';
...
ydoc = new Y.Doc();
constructor() {
// String data in indexdb of browser
const indexeddbProvider = new IndexeddbPersistence('todoList', this.ydoc)
// Getting contents of array from document created.
this.yarray = this.ydoc.getArray("todoList");
// Creating a websocket connection between users.
this.websocketProvider = new WebsocketProvider(
"wss://demos.yjs.dev",
"todoList",
this.ydoc
);
}
// Function for inserting Data into array
insert() {
this.array = [];
this.array.push(this.value);
this.ydoc.getArray("todoList").insert(0, this.array);
}
// Function for making connection between users.
connect() {
if (this.websocketProvider.shouldConnect) {
this.websocketProvider.disconnect();
this.textContent = "Connect";
} else {
this.websocketProvider.connect();
this.textContent = "Disconnect";
}}
}
  • Ниже приведен код HTML-части для создания текстового поля для получения задач от пользователей.
<!-- Input Field for adding Todo -->
<div class="col-lg-12">
<input type="text" class="form-control textbox" [(ngModel)]="value" />
</div>
<!-- Showing Task that has been entered by multiple users -->
<h4>List of Tasks :</h4>
<div *ngFor="let item of yarray" class="row mt-1">
<div class="col-12 col-md-11 list-todo">
<p><span class="font-weight-bold">Task</span> : {{ item }}</p>
</div>
</div>
<!-- Button for disconnecting/connecting connection between users -->
<button style="margin-left: 40%;" class="btn button" (click)="connect()">{{ textContent }}</button>
  • Взгляд на приложение ниже показывает, как пользователи могут включать задачи в режиме реального времени.

Мы успешно создали приложение TODO в реальном времени с использованием CRDT для устранения конфликтов. Это поможет нам легко сотрудничать с нашими товарищами по команде и документировать данные. Перейдите по ссылке Ссылка на репозиторий Github, чтобы просмотреть полный исходный код.

Резюме

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

Спасибо, что прочитали руководство. Просим вас поделиться своими мыслями в комментариях ниже!

использованная литература

О Blocksurvey

BlockSurvey - это платформа, ориентированная на конфиденциальность, для создания опросов, опросов и форм с полной конфиденциальностью. Благодаря BlockSurvey все ваши данные зашифрованы от начала до конца, и только вы можете их увидеть. Вы владеете своими данными. Это ваше цифровое право. Здесь нет трекеров, и мы сохраняем вашу анонимность для сборщиков данных. Наша платформа использует Blockstack и помогает поддерживать конфиденциальность и анонимность, что позволяет проводить эффективные опросы и опросы. Попробуйте создать свои опросы и опросы вместе с нами.