Як заощадити під час співпраці в режимі реального часу


10

Я хочу, щоб кілька користувачів редагували один і той же документ. Проблема, з якою я стикаюся, полягає в тому, що коли приєднується новий користувач, він може побачити застарілий документ. Як зробити так, щоб нові користувачі отримували останні зміни?

Деякі рішення, про які я думав:

  • Економте на кожній зміні. Мені не подобається це рішення, оскільки воно сповільнить роботу інтерфейсу та навантажить на db.

  • Коли приєднується новий користувач, запустіть економію на всіх інших клієнтах. Після збереження інших клієнтів завантажте документ. З цим все-таки може бути непослідовність.

Будь-які інші пропозиції будуть корисні.

ОНОВЛЕННЯ: Після розгляду запропонованого рішення, API Google Realtime, я з’ясував, що:

  1. Користувачі вашої програми повинні мати Диск Google і надавати вам доступ до їх диска . Це може в кращому випадку представляти незручний потік інтерфейсу користувача або заважати користувачам, які не мають Google Диска, користуватися функцією в режимі реального часу.

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

UPDATE 2: Для acoomplish мети, я пішов з Firebase від Google


Чому існує різниця між новим користувачем і вже активними користувачами, які редагують / переглядають один і той же документ?
Енді

@Andy Те, що я зараз роблю, - це трансляція через сокети, всі зміни, які вносять користувачі. Ці зміни оновлюють інтерфейс користувача для користувачів, у яких браузери відкриті, але вони не миттєво зберігаються в базі даних. Тож у мене виникає ситуація, коли приєднується новий користувач, він завантажує документ із бази даних, і він не бачить усіх останніх змін, які ще не були збережені.
dev.e.loper

1
якщо ви вже надсилаєте зміни і хочете залишити таку поведінку, як зараз, ви можете попросити одного з клієнтів надіслати останній вигляд новому клієнту або у вас може бути один віртуальний клієнт на сервері, який отримує всі зміни і коли новий клієнт приєднується, надсилає останні вид на це.
Даїній

Відповіді:


14

Google Диск

Якщо ви намагаєтеся створити власну версію документів Google, пропоную переглянути API Google Realtime . Нещодавно Google випустив це з наміром дозволити іншим розробникам використовувати ті самі інструменти, які вони зробили для співпраці в режимі реального часу. Це дозволить вам заощадити час на розвиток і швидше отримати робочий продукт.

Ви можете легко взяти дані, що знаходяться в документі, і регулярно заштовхувати їх у свою базу даних, або ж сама база даних буде "учасником" обміну, просто слухаючи та записуючи всі зміни. Він також дозволяє користувачеві визначити власну структуру даних, яка потім може бути використана в API реального часу, тож ви можете розширити їх, як вважаєте за потрібне.

Диск, який не належить Google

Отже, згідно з вашими дослідженнями, Google Drive не є можливим. Це добре, але це буде складніше і, можливо, не спрацює, залежно від того, скільки ви вкладете в нього.

Ось загальна стратегія, яку я б використав для вирішення цієї проблеми:

  1. Нехай сервер буде мультиплексором зв'язку. Кожна людина розмовляє з сервером, і сервер передає цю інформацію всім іншим. Таким чином, сервер завжди має найновіший перегляд документа.

  2. Знайдіть сторонній алгоритм / модуль для вирішення конфлікту. Вирішення конфліктів важко, і це все ще не ідеально. Це зробити самостійно, може легко збільшити масштаб проекту, який буде занадто великим. Якщо ви не можете використовувати алгоритм сторонніх розробників, я б запропонував вам дозволити лише одному користувачеві редагувати область часу, так що користувач повинен отримати блокування перед редагуванням області, або ви ризикуєте знищити роботу інших користувачів, які стане дуже старим, дуже швидко

  3. Коли приєднується новий користувач, надайте їм останній документ і автоматично почніть передавати їм команди. Сервер має найновіший вигляд, і тому він може автоматично вимикати його.

  4. Резервне копіювання в базу даних через певні проміжки часу. Вирішіть, як часто ви хочете створювати резервну копію (кожні 5 хвилин або, можливо, кожні 50 змін.) Це дозволяє вам підтримувати потрібну резервну копію.

Проблеми: це не ідеальне рішення, тому ось деякі проблеми, з якими ви можете зіткнутися.

  1. Пропускна здатність сервера могла б мати вузькі місця

  2. Занадто багато людей, які читають / пишуть, можуть перевантажити сервер

  3. Люди можуть не синхронізуватися, якщо повідомлення втрачено, тож ви можете переконатися, що ви синхронізувались у звичайних точках. Це означає, що ще раз відправити все повідомлення, що може бути дорого, але в іншому випадку люди можуть не мати того самого документа і не знати його.


Так, зміни передаються всім клієнтам, і їх версія (сподіваємось однакова) у браузері. Здається, що ви говорите, що оновлення документа про кожну дію - це шлях?
dev.e.loper

Або хоча б мати регулярні часові рамки синхронізації, коли поточний стан документа передається у фоновому режимі, щоб переконатися, що всі знаходяться на одній сторінці. Як часто залежатиме від того, наскільки швидко люди будуть змінювати документ. Таким чином у вас вже є усталений метод надсилання нових людей, а також можливість переконатися, що він ніколи не сильно розходиться.
квітня 1313

1
+1. Не ускладнюйте життя. Google робить це добре, не потребуючи винаходити колесо.
Ніл

Чи зберігає Google Realtime на Google Drive? Я хочу зберегти у своїй базі даних, а не на Google Диску.
dev.e.loper

@ dev.e.loper додав інформацію про це у відповідь за вас.
1313

3

Я рекомендую 1 стійку копію документа на сервері. Коли клієнт підключається до сервера, ви видаєте UPDATEкоманду (и) цьому клієнту з усіма змінами.

Оновити WorkFlow

Користувач викликає запуск змін -> Клієнт надсилає UPDATEна Сервер -> Сервер надсилає UPDATEКлієнтам

Життєздатні тригери

  1. Користувач натискає Зберегти
  2. Користувач виконує конкретне завдання
    • Завершує редагування комірки
    • Завершує редагування речення / абзацу / рядка
  3. Користувач натискає Скасувати
  4. Користувач натискає клавішу повернення
  5. Користувач вводить ключ (збережіть при кожній зміні)

Оновлення Впровадження

Я б запропонував можливість повторно створити документ за допомогою серії UPDATEкоманд, щоб сервер зберігав кожну ОНОВЛЕННЯ, і коли новий клієнт підключається, клієнт може надіслати ряд оновлень, а сам може відновити документ для відображення в користувач. Крім того, ви можете також мати окрему SAVEкоманду і UPDATE бути тимчасовими змінами, які можна використовувати для UNDOзапитів, і SAVE фактично зберігає її для повторного відкриття, якщо сервер закритий або всі клієнти відключені.


2
А як щодо вирішення конфлікту? Що робити, якщо двоє людей одночасно редагують одну і ту ж область тексту? Крім того, це, здається, створює навантаження на БД, чого ОП намагалося уникнути. Це може бути життєздатним для того, що йому потрібно.
1313

@Ampt Я створив електронну таблицю за допомогою цієї моделі, і для конфліктів кожне конкретне завдання, яке оновлювалося, було повністю замінено на новітню версію. Таким чином, остання особа, яка закінчила редагування комірки, замінила б попередньо оновлену клітинку повністю без об’єднання.
Корей Хінтон

1
Тож одне речення замінило б інше, якби це, скажімо, документ слова?
1313

@Ampt так, або ви могли реалізувати спосіб блокування того, над чим працюєте, але я взяв простий шлях.
Корей Хінтон

3

1) Погляньте на Knockout.js

Він дотримується шаблону MVVM і автоматично виштовхує сповіщення у Перегляд на основі змін у Моделі. Наприклад, загляньте в їхній видимий масив, щоб надати трохи більше інформації про те, як вони це роблять.

2) Змішайте це з SignalR, і тепер у вас має можливість надсилати сповіщення іншим користувачам, які працюють над документом. З їх сайту:

SignalR також пропонує дуже простий API високого рівня для роботи сервера з клієнтом RPC (виклик функцій JavaScript у браузерах ваших клієнтів із боку сервера .NET-коду) у вашій програмі ASP.NET, а також додавання корисних гаків для управління з'єднаннями. , наприклад, підключити / відключити події, групувати з'єднання, авторизацію.

Таким чином, вам потрібно буде мати кілька гачків на рівні вашої моделі в Knockout.js, щоб здійснити деякі дзвінки SignalR щоразу, коли відбудеться зміна. Інші клієнти отримають повідомлення від SignalR, а потім запустить відповідну зміну своєї копії Моделі, яка повернеться назад до їх перегляду.

Це цікаве поєднання двох каркасів, і ви повинні мати можливість шукати та збирати більше інформації для обробки деталей.

Наприклад, цей приклад кодового проекту конкретно адресує, Co Working UIs and Continuous Clientsщо, здається, саме те, що ви намагаєтеся зробити.

Веб-програмам New Age, можливо, потрібно запропонувати користувачеві нового віку - і вони повинні правильно обробляти співпрацюючі та постійні сценарії клієнтів. Це передбачає, що користувальницький інтерфейс належним чином синхронізується на всіх пристроях та у всіх користувачів, щоб забезпечити збереження стану програми та інтерфейсу користувача "як є".

Ця публікація блогу виглядає як вхідний пункт до ряду публікацій блогу, де обговорюється використання двох пакетів та протиставляється традиційному підходу ASP.NET. Може запропонувати деякі пункти для розгляду під час проектування вашого веб-сайту.

Ця публікація в блозі, як видається, є трохи більш базовою і дає основу для поєднання двох пакетів.

Розкриття інформації: я не пов’язаний ні з одним із перерахованих вище посилань, ні я дійсно не вникав у їхній зміст, щоб побачити, наскільки це звучить чи правильно.


2

Рішення - операційна трансформація (ОТ). Якщо ви ще не чули про це, OT - це клас алгоритмів, які забезпечують одночасність одночасності багатосайтової роботи. OT - це як git в реальному часі. Він працює з будь-якою кількістю відставання (від нуля до тривалої відпустки). Це дозволяє користувачам робити прямі та паралельні редагування з низькою пропускною здатністю. OT дає вам можливу узгодженість між декількома користувачами без повторних спроб, без помилок і без перезапису даних.

Але реалізація ОТ є складним завданням і забирає багато часу. Тому ви можете використовувати зовнішню бібліотеку, наприклад http://sharejs.org/ .


1
API Google Realtime робить OT youtu.be/hv14PTbkIs0?t=14m20s Вони роблять це як на клієнті, так і на сервері. Я не зміг отримати чітку відповідь, прочитавши документи ShareJS, але я припускаю, що ShareJS робить OT як на клієнті, так і на сервері?
dev.e.loper

1

Це головним чином залежить від типу ваших документів та того, як співпрацюють ваші користувачі.

Однак я б:

  1. нехай усі клієнти раз на час надсилають збережені зміни на сервер (залежить від того, як користувачі працюють з документами).
  2. сервер зберігає дельти в сеансі користувача (навіть для товстого клієнта вам потрібно щось на зразок сеансу)
  3. інші клієнти, що редагують / переглядають один і той же документ, отримують тимчасові зміни або принаймні натяк на те, що це може бути.

Переваги:

  • немає оновлень БД, якщо хтось не натисне "Зберегти"
  • резервна копія на випадок, коли клієнт виходить з ладу (за період сеансу)
  • ваш сервер вирішує, як і які дані переслати клієнту (наприклад, ви можете перейти запустити функцію за допомогою лише нотатки, а потім реалізувати більш складне об'єднання та виділення)

Недоліки:

  • не "в режимі реального часу" - наприклад, ви надсилаєте кожні 30 секунд, але хтось набирає 3 пропозиції за цей час.
  • більше мережевого трафіку - залежно від ваших документів та співпраці
  • можливо великі сеанси
  • можливо, великі зусилля для обчислення, якщо багато користувачів співпрацюють і вносять багато змін

1

По суті, ви запитуєте, як поводитися зі спільним змінним станом. Економія - це легка частина; але як ви маєте справу з кількома людьми, що редагують одну і ту ж річ одночасно? Ви хочете, щоб усі користувачі переглядали один і той же документ під час синхронізації одночасних редагувань, і все це в режимі реального часу.

Як ви, напевно, зібралися, це важка проблема! Є кілька прагматичних рішень:

  1. Змініть свої вимоги до програми, щоб не допускати правдивого одночасного редагування. Правки можна об'єднати, як із системами управління джерелами, з результатами, що передаються кожному клієнту. Ви можете створити це самостійно, але це буде біднішим користувачем.
  2. Аутсорсинг синхронізації мутацій стану на рішення з відкритим кодом, що інтегрується з вашою існуючою технологією. ShareDB - поточний лідер у цьому просторі. Він заснований на операційній трансформації та використовується щонайменше в одній виробничій системі. Це допоможе вирішити проблему збереження, яка вас цікавить, але не допоможе жодним із додаткових функцій UX, обов'язкових для будь-якого спільного застосування.
  3. Використовуйте нестандартну платформу, таку як Конвергенція (відмова: я засновник), щоб обробити всі складні для вас біти. Ви також отримаєте додаткові інструменти для співпраці в режимі реального часу, такі як відстеження курсору / миші, вибір та чат для швидкого створення найкращого досвіду спільної роботи. Дивіться це питання, щоб отримати гарний опис усіх існуючих інструментів там.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.