فرق فعال في الشبكة بين سلسلتين في جافا سكريبت

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

  •  21-09-2019
  •  | 
  •  

سؤال

لديّ تطبيق ويب حيث يقوم محرر جانب العميل بتحرير نص كبير حقًا معروف على جانب الخادم.

يمكن للعميل إجراء أي نوع من التعديلات على هذا النص.

ما هو أكثر فعال الشبكة طريقة لنقل فرق النتيجة بطريقة يفهمها الخادم؟ أيضًا ، نظرًا لأن هذا سيحدث على جانب العميل (JavaScript) ، أود أيضًا أن يكون "سريعًا" (أو على الأقل ليس بطيئًا بشكل ملحوظ)

بعض السيناريوهات:

  • المستخدم يعدل حرف واحد
  • يقوم المستخدم بتعديل عدة جمل في مواضع عشوائية
  • يمسح المستخدم كل شيء ويؤدي إلى نص فارغ.

لا يمكنني استخدام بناء جملة يشبه الفرق لأنه ليس فعالًا للشبكة ، فهو يتحقق من الخطوط ، حيث ينتج عن الأمثلة 1 و 3 اختلافات مروعة (خاصةً آخرها ، حيث ستكون النتيجة أكثر من القديم نفسها).

أي شخص لديه خبرة في هذا الأمر؟ يعمل المستخدم على مجموعة كبيرة من البيانات-حوالي 3-5 ميغابايت من النص ، وتحميل المحتوى "الجديد" بالكامل هو لا يوجد شيء كبير.

لكي أكون واضحًا ، أنا أبحث عن "بروتوكول" للنقل ، فإن مقارنة السلسلة ليست هي المشكلة.

هل كانت مفيدة؟

المحلول

لست على دراية بهذا الموضوع ، لكن يمكنني توجيهك إلى مشروع مفتوح المصدر (Apache License 2.0) والذي قد يكون مفيدًا للغاية.

إنها مكتبة مختلفة ومطابقة وتصحيح مكتوبة بعدة لغات ، بما في ذلك JavaScript ، من مهندس Google ويتم استخدامها في العديد من خدمات التحرير التعاونية عبر الإنترنت.

فيما يلي قائمة بالموارد:

نصائح أخرى

إن النهج البسيط ، على افتراض أنك تعرف النسخة الموجودة على الخادم لن تتغير ، سيكون مجرد إرسال قائمة بالتحرير (الحذف والإضافات) ، مع تمثيل الحذف كفهرس بداية ونهاية ، والإضافات الممثلة كفهرس البدء والنص لإدراج.

إذا كان لديك أكثر من مجرد خوارزمية فرق بسيطة للعمل معها (لست متأكدًا تمامًا مما تعنيه "مقارنة السلسلة ليس المشكلة") ، فيمكنك أيضًا اكتشاف أجزاء النص المنقولة أو نسخها ، وإرسالها كبداية وفهرس النهاية للقطعة المنقولة أو النسخ ، وكذلك الوجهة لإدراجها.

لاحظ أنك ستحتاج إلى التأكد من تتبع ما إذا كانت مؤشراتك تشير إلى المستند الأصلي ، أو المستند كما تم تحريره حتى الآن. هناك نهج سهل لتجنب هذه المشكلة هو إجراء التعديلات دائمًا من نهاية المستند نحو البداية ؛ ثم لن تؤثر التعديلات السابقة على الإزاحة المحددة عن طريق التعديلات اللاحقة.

للحصول على مثال على مثل هذا ، انظر ed تنسيق ذلك diff -e المخرجات. هذا هو في الأساس إدخال يمكن إطعامه في ed محرر النص الموجهة نحو الخط. إذا كنت تريد إرسال أصغر الفرق المطلقة ، فقد ترغب في القيام بفهرسة قائمة على الحرف بدلاً من الفهرسة القائمة على الخط ، ولكن قد ينجح نفس النهج الأساسي.

يمكن تقسيم أي تعديلات على أداء المستخدم بكفاءة إلى: حذف من x للطول y ؛ أدخل في نص x "أيا كان". X و Y هما من الأحرف من بداية النص ؛ Y هو عدد من الأحرف ؛ "أيا كان" هو أي سلسلة من الأحرف. أنت تقول أنك لا تحتاج إلى مساعدة في حساب الفرق ، ولكن مثال هنا, ، باستثناء أنه أكثر ثراءً في إنتاجه مما تحتاج إليه ، ولكنه يحدد "عمليات الإزالة والإدراج" ، لذلك ، فقط قم بتغيير جزء الإخراج.

يمكن ضبط التنسيق الدقيق الذي ترسل فيه البيانات إلى الخادم ، لكنني لا أعتقد أن هناك الكثير من الأميال في القيام بذلك - في انتظار القياس ، سأبدأ بإرسال الأوامر كـ D للحذف أو لإدراج ، الأرقام في العشرية ، السلسلة المدرجة في شكل مقتبس. بمجرد أن يكون لديك بعض الإحصائيات حول إجراء عمليات النقل الفعلية ، يمكنك أن ترى مقدار النفقات العامة في الأرقام (العشرية مقابل الثنائية) والاقتباسات ، لكنني أظن أنه قد لا يكون هذا كله ذا معنى (إذا ثبت أن هناك كل شيء من الأشياء التي يمكنك تجربتها ، مثل إعطاء تعويضات من آخر نقطة إدراج أو حذف ، وليس دائمًا من البداية ، لجعل الأمور أسرع).

يمكنك أخذ عينات مما يفعله المستخدم كل بضع ثوانٍ ، وإرسال التغييرات الإضافية على مدار تلك الثواني القليلة الماضية (إن وجدت) - وبهذه الطريقة ، ستكون كل حزمة ترسلها صغيرة ، وإذا كانت اتصال الشبكة أو المستخدم تعطل الكمبيوتر/المتصفح ، لن يفقد المستخدم الكثير من العمل.

يمكنك فقط إرسال تغييرات كل 500 مللي ثانية ، لذلك ، أيا كانت التغييرات التي تم إجراؤها في آخر 500 مللي ثانية سيتم إرسالها ، لكنك ترسل البيانات فقط عندما يكون هناك تغيير.

في هذا ، يمكنك بعد ذلك إرسال موضع الكلمات (الكلمات) التي تم تغييرها وإرسال الكلمة بأكملها ، لكن سيكون لدي الموضع من مقدمة النص.

لن تكون قيمة عدة جمل ، ولكن قد يكون هناك عدة كلمات متضمنة ، ولكن إذا أرسلتها حسب ترتيب التغيير ، فيجب أن تكون النتيجة متسقة.

لأن هناك العديد من الطرق لإجراء التعديلات-حتى في غضون فترات زمنية قصيرة مثل 500 مللي ثانية-بما في ذلك سحب وإسقاط ، أو قطع ولصق ، أقسام نصية كبيرة داخل المستند أو من خارجها-لا أعرف ما إذا كان هناك شيء سيغطي جميع السيناريوهات جيدًا. هذا بالتأكيد غير إجابات لسؤالك بالقيمة الاسمية ، لكنني سأعتبر بعناية مشكلة تطوير وصيانة شيء كهذا مقارنةً بتغيير الواجهة لتقييد حجم النص وكسر النصوص الموجودة إلى قطع أصغر.

ربما لا يكون ذلك ممكنًا في وضعك ، ولكن إذا كان الأمر كذلك ، أعتقد أنه سيكون أقل بكثير في النهاية لتفادي المشكلة بهذه الطريقة وإرسال مستندات كاملة بعد التحرير.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top