Сеть-эффективная разница между двумя строками в JavaScript

StackOverflow https://stackoverflow.com/questions/1576050

  •  21-09-2019
  •  | 
  •  

Вопрос

У меня есть веб -приложение, в котором редактор клиента редактирует действительно действительно большой текст, который известен на стороне сервера.

Клиент может внести какие -либо изменения в этот текст.

Что самое большее сетевой экономичный Способ передать разницу результатов так, как сервер понимает? Кроме того, поскольку это произойдет на стороне клиента (JavaScript), я также хотел бы, чтобы это было «быстро» (или, по крайней мере, не заметно медленно)

Некоторые сценарии:

  • Пользователь изменяет один символ
  • Пользователь изменяет несколько предложений в случайных позициях
  • Пользователь стирает все и приводит к пустому тексту.

Я не могу использовать Diff-подобный синтаксис, поскольку он не эффективен сеть, он проверяет линии, где примеры 1 и 3 будут вызывать ужасные различия (особенно последний, где результат будет больше, чем сам старый).

У кого -нибудь есть опыт в этом вопросе? Пользователь работает на действительно большом наборе данных-около 3-5 МБ текста, а загрузка всего «нового» контента-это большой нет-нет.

Чтобы быть ясным, я ищу «протокол» передачи, сравнение строк не является проблемой.

Это было полезно?

Решение

Я не очень знаком с этой темой, но я могу указать вам на проект с открытым исходным кодом (Apache License 2.0), который может быть очень полезен.

Это библиотека Diff, Match и Patch, написанная на нескольких языках, в том числе JavaScript, от инженера Google, и используется в нескольких онлайн -службах совместного редактирования.

Вот список ресурсов:

Другие советы

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

Если у вас есть больше, чем простой алгоритм Diff для работы (я не уверен, что именно вы подразумеваете под «сравнением строк не является проблемой»), вы также можете обнаружить перемещенные или скопированные куски текста и отправить их как начало и конечный индекс перемещенного или скопированного текста, а также пункт назначения для его вставки.

Обратите внимание, что вам нужно будет следить за тем, ссылаются ли ваши индексы к исходному документу или документу, как отредактированный. Легкий подход, чтобы избежать этой проблемы, - всегда выполнять изменения с конца документа к началу; Тогда более ранние изменения не повлияют на смещения, указанные в более поздних редакциях.

Для примера такого подхода см. В ed формат это diff -e выходы. Это в основном вход, который можно воодушевить в ed Линейный текстовый редактор. Анкет Если вы хотите, чтобы абсолютные самые маленькие различия были отправлены, вы можете выполнять индексацию на основе персонажа, а не индексацию на основе линии, но тот же базовый подход может работать.

Любые изменения, которые выполняет пользователя, может быть эффективно разбит на: удалить из x для длины y; Вставьте в x текст "что угодно". X и y - смещения в символах с самого начала текста; Y - это количество символов; «Что бы» ни была любая строка символов. Вы говорите, что вам не нужна помощь в вычислении DIFF, но пример здесь, за исключением того, что он богаче в своем выходе, чем вам нужно, но выявляет «удаления и вставки», поэтому просто измените выходную часть.

Точный формат, в котором вы отправляете данные на сервер, можно настроить, но я не думаю, что в этом есть много пробега - в ожидании измерения, я бы начал с отправки команд как D для Delete или I для вставки, Числа в десятичном, вставленная строка в цитируемой форме. После того, как у вас есть некоторые статистические данные о фактических переводах, вы можете увидеть, сколько накладных расходов находится в цифрах (десятичное и двоичное) и цитаты, но я подозреваю Из вещей, которые вы можете попробовать, например, предоставление смещений с последней точки введения или удаления, а не всегда с самого начала, чтобы сделать вещи быстрее).

Вы можете попробовать то, что пользователь делает каждые несколько секунд, и просто отправлять дополнительные изменения за последние несколько секунд (если таковые имеются) - таким образом, каждый пакет, который вы отправляете, будет небольшим, и если сетевое соединение или пользователь Сбой компьютера/браузера пользователь не потерял много работы.

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

В этом вы можете отправить позицию измененного слова (-ы) и просто отправить все слово, но я бы был из передней части текста.

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

Потому что есть так много способов сделать изменения-даже в течение коротких периодов времени, как 500 мс-включая перетаскивание и сбрасывание, или разрезание и вставка, большие разделы текста в документе или снаружи его-Я не знаю, будет ли что-то, что будет охватывать все сценарии очень хорошо. Это, безусловно, не отвечает вашему вопросу по стоимости лица, но я бы тщательно рассмотрел проблему разработки и поддержания чего-то подобного по сравнению с изменением интерфейса, чтобы ограничить размер текста и разорвать существующие тексты на более мелкие части.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top