วิธีบันทึกระหว่างการทำงานร่วมกันแบบเรียลไทม์


10

ฉันต้องการให้ผู้ใช้หลายคนแก้ไขเอกสารเดียวกัน ปัญหาที่ฉันเผชิญคือเมื่อผู้ใช้ใหม่เข้าร่วมเขาอาจเห็นเอกสารที่ล้าสมัย ฉันจะแน่ใจได้อย่างไรว่าผู้ใช้ใหม่ได้รับการเปลี่ยนแปลงล่าสุด

วิธีแก้ปัญหาที่ฉันคิด:

  • ประหยัดทุกการเปลี่ยนแปลง ฉันไม่ชอบโซลูชันนี้เพราะจะทำให้ช้าลงใน UI และทำให้โหลดบน db

  • เมื่อผู้ใช้ใหม่เข้าร่วมทริกเกอร์บันทึกลูกค้าอื่น ๆ ทั้งหมด หลังจากบันทึกไคลเอนต์อื่นแล้วให้โหลดเอกสาร ด้วยสิ่งนี้จะยังคงไม่สอดคล้องกัน

ข้อเสนอแนะอื่น ๆ จะเป็นประโยชน์

อัปเดต:หลังจากดูวิธีการแก้ปัญหาที่แนะนำแล้ว Google Realtime API ฉันพบว่า:

  1. ผู้ใช้แอปของคุณจะต้องมี Google ไดรฟ์และให้คุณเข้าถึงไดรฟ์ของพวกเขา สิ่งนี้อาจทำให้เกิดการไหลของ UI ที่น่าอึดอัดใจที่สุดหรือป้องกันผู้ใช้ที่ไม่มี Google Drive จากการใช้คุณสมบัติเรียลไทม์

  2. การตั้งค่าการแชร์ทั้งหมดที่อยู่ข้างคุณต้องทำซ้ำสำหรับเอกสาร Google

อัปเดต 2:เพื่อบรรลุเป้าหมายฉันไปกับFirebase ของ Google


เหตุใดจึงมีความแตกต่างระหว่างผู้ใช้ใหม่กับผู้ใช้งานที่กำลังแก้ไข / ดูเอกสารเดียวกันอยู่แล้ว?
Andy

@Andy สิ่งที่ฉันกำลังทำอยู่คือการออกอากาศผ่านซ็อกเก็ตการเปลี่ยนแปลงทั้งหมดที่ผู้ใช้ทำ การเปลี่ยนแปลงเหล่านี้อัปเดต UI สำหรับผู้ใช้ที่เปิดเบราว์เซอร์ แต่ไม่ได้บันทึกลงในฐานข้อมูลทันที ดังนั้นฉันจึงมีสถานการณ์เมื่อผู้ใช้ใหม่เข้าร่วมเขาโหลดเอกสารจากฐานข้อมูลและเขาไม่เห็นการเปลี่ยนแปลงล่าสุดทั้งหมดที่ยังไม่ได้บันทึก
dev.e.loper

1
ถ้าคุณส่งการเปลี่ยนแปลงไปแล้วและต้องการออกจากพฤติกรรมเดิมเหมือนตอนนี้คุณสามารถขอให้ลูกค้าคนหนึ่งส่งมุมมองล่าสุดไปยังไคลเอนต์ใหม่หรือคุณสามารถมีไคลเอนต์เสมือนหนึ่งบนเซิร์ฟเวอร์ที่ได้รับการเปลี่ยนแปลงทั้งหมดและเมื่อลูกค้าใหม่เข้าร่วมส่งล่าสุด ดูมัน
Dainius

คำตอบ:


14

Google Drive

ถ้าคุณกำลังพยายามที่จะทำให้รุ่นของคุณเอง Google เอกสารผมขอแนะนำให้คุณลองดูที่มาของ Google Realtime API Google เพิ่งเปิดตัวสิ่งนี้โดยมีเจตนาอนุญาตให้นักพัฒนาซอฟต์แวร์รายอื่นใช้เครื่องมือเดียวกับที่พวกเขาทำเพื่อให้สามารถทำงานร่วมกันแบบเรียลไทม์ สิ่งนี้จะช่วยให้คุณประหยัดเวลาในการพัฒนาและใช้งานผลิตภัณฑ์ได้เร็วขึ้น

คุณสามารถนำข้อมูลที่อยู่ในเอกสารและส่งไปยังฐานข้อมูลของคุณเป็นระยะ ๆ หรือทำให้ฐานข้อมูลนั้นเป็น 'ผู้เข้าร่วม' ของการแลกเปลี่ยนเพียงแค่ฟังและบันทึกการเปลี่ยนแปลงทั้งหมด นอกจากนี้ยังช่วยให้ผู้ใช้สามารถกำหนดโครงสร้างข้อมูลของตนเองซึ่งสามารถใช้งานได้ในเรียลไทม์ API ดังนั้นคุณสามารถขยายได้ตามที่เห็นสมควร

ไม่ใช่ไดรฟ์ของ Google

ดังนั้นจากการวิจัยของคุณ Google Drive จึงไม่ใช่ตัวเลือก ไม่เป็นไร แต่มันจะยากขึ้นและอาจไม่ได้ผลเช่นกันขึ้นอยู่กับว่าคุณใส่เข้าไปมากน้อยแค่ไหน

นี่เป็นกลยุทธ์ทั่วไปที่ ฉันจะใช้เพื่อทำให้ปัญหานี้สำเร็จ:

  1. ให้เซิร์ฟเวอร์เป็นตัวสื่อสารมัลติเพล็กเซอร์ แต่ละคนพูดคุยกับเซิร์ฟเวอร์และเซิร์ฟเวอร์ส่งข้อมูลนั้นให้กับคนอื่น วิธีนี้เซิร์ฟเวอร์จะมีมุมมองที่ทันสมัยที่สุดของเอกสารเสมอ

  2. ค้นหาอัลกอริทึม / โมดูลของบุคคลที่สามเพื่อแก้ไขข้อขัดแย้ง การแก้ไขข้อขัดแย้งนั้นยากและเป็นสิ่งที่ยังไม่สมบูรณ์แบบ การทำเช่นนี้เพียงอย่างเดียวสามารถเพิ่มขอบเขตของโครงการให้ใหญ่เกินไปได้อย่างง่ายดาย หากคุณไม่สามารถใช้อัลกอริทึมของบุคคลที่สามได้ฉันขอแนะนำให้คุณอนุญาตให้ผู้ใช้หนึ่งรายทำการแก้ไขพื้นที่หนึ่งครั้งเพื่อให้ผู้ใช้ต้องได้รับการล็อคก่อนทำการแก้ไขพื้นที่หรือคุณเสี่ยงต่อการทำลายผู้ใช้รายอื่น จะแก่มากเร็วมาก

  3. เมื่อผู้ใช้ใหม่เข้าร่วมให้พวกเขาเอกสารล่าสุดและเริ่มสตรีมคำสั่งให้พวกเขาโดยอัตโนมัติ เซิร์ฟเวอร์มีมุมมองล่าสุดและสามารถลบออกโดยอัตโนมัติ

  4. สำรองข้อมูลไปยังฐานข้อมูลในช่วงเวลาที่แน่นอน กำหนดความถี่ที่คุณต้องการสำรองข้อมูล (ทุกๆ 5 นาทีหรืออาจมีการเปลี่ยนแปลงทุกๆ 50 ครั้ง) สิ่งนี้ช่วยให้คุณสามารถสำรองข้อมูลที่คุณต้องการ

ปัญหา:นี่ไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์แบบดังนั้นนี่คือปัญหาที่คุณอาจประสบ

  1. ปริมาณงานของเซิร์ฟเวอร์อาจทำให้ประสิทธิภาพการทำงานลดลง

  2. มีคนจำนวนมากที่อ่าน / เขียนเกินเซิร์ฟเวอร์ได้

  3. ผู้คนอาจไม่ซิงค์กันหากข้อความหายไปดังนั้นคุณอาจต้องการทำให้แน่ใจว่าคุณซิงโครไนซ์ที่จุดปกติ นี่หมายถึงการส่งข้อความทั้งหมดอีกครั้งซึ่งอาจมีค่าใช้จ่ายสูง แต่มิฉะนั้นผู้คนอาจไม่มีเอกสารเดียวกันและไม่ทราบ


ใช่การเปลี่ยนแปลงถูกถ่ายทอดไปยังไคลเอนต์ทั้งหมดและพวกเขามีเวอร์ชัน (หวังว่าเหมือนกัน) บนเบราว์เซอร์ ดูเหมือนคุณกำลังบอกว่าการอัพเดทเอกสารในทุก ๆ การกระทำเป็นวิธีการหรือไม่?
dev.e.loper

หรืออย่างน้อยก็มีกรอบเวลา 'ซิงค์' ปกติซึ่งสถานะปัจจุบันของเอกสารจะถูกส่งออกในพื้นหลังเพื่อให้แน่ใจว่าทุกคนอยู่ในหน้าเดียวกัน ขึ้นอยู่กับว่าผู้คนจะเปลี่ยนแปลงเอกสารเร็วแค่ไหน ด้วยวิธีนี้คุณมีวิธีการที่กำหนดไว้แล้วสำหรับการส่งถึงผู้คนใหม่ ๆ รวมถึงความสามารถในการทำให้แน่ใจว่ามันจะไม่เบี่ยงเบนไปมากเกินไป
Ampt

1
+1 อย่าทำให้ชีวิตลำบาก Google ทำได้ดีโดยไม่ต้องคิดค้นใหม่
Neil

Google เรียลไทม์บันทึกลงใน Google Drive หรือไม่ ฉันต้องการบันทึกลงในฐานข้อมูลไม่ใช่ Google ไดรฟ์
dev.e.loper

@ dev.e.loper ได้เพิ่มข้อมูลเกี่ยวกับคำตอบสำหรับคุณ
Ampt

3

ฉันขอแนะนำ 1 สำเนาถาวรของเอกสารบนเซิร์ฟเวอร์ เมื่อไคลเอนต์เชื่อมต่อกับเซิร์ฟเวอร์คุณออกUPDATEคำสั่งไปยังไคลเอนต์ที่มีการเปลี่ยนแปลงทั้งหมด

อัปเดตเวิร์กโฟลว์

ผู้ใช้ทำให้เกิดการเปลี่ยนแปลงทริกเกอร์ -> ไคลเอ็นต์ส่งUPDATEไปยังเซิร์ฟเวอร์ -> เซิร์ฟเวอร์ส่งUPDATEไปยังลูกค้า

ทริกเกอร์ที่ทำงานได้

  1. ผู้ใช้คลิกบันทึก
  2. ผู้ใช้ทำงานที่เฉพาะเจาะจงให้เสร็จสมบูรณ์
    • แก้ไขเซลล์ให้เสร็จสิ้น
    • สิ้นสุดการแก้ไขประโยค / ย่อหน้า / บรรทัด
  3. ผู้ใช้คลิกเลิกทำ
  4. ผู้ใช้กดปุ่มย้อนกลับ
  5. ผู้ใช้พิมพ์รหัส (บันทึกการเปลี่ยนแปลงทุกครั้ง)

การปรับปรุงการใช้งาน

ฉันขอแนะนำให้สามารถสร้างเอกสารใหม่ด้วยชุดUPDATEคำสั่งเพื่อให้เซิร์ฟเวอร์จัดเก็บแต่ละ UPDATE และเมื่อไคลเอนต์ใหม่เชื่อมต่อไคลเอนต์สามารถส่งชุดของการปรับปรุงและตัวมันเองสามารถสร้างเอกสารเพื่อแสดง ผู้ใช้งาน. นอกจากนี้คุณอาจมีSAVEคำสั่งแยกต่างหากและมี UPDATE เป็นการเปลี่ยนแปลงชั่วคราวที่สามารถใช้สำหรับUNDOการร้องขอและให้ SAVE จัดเก็บจริงเพื่อให้เปิดขึ้นมาใหม่หากเซิร์ฟเวอร์ถูกปิดหรือไคลเอนต์ทั้งหมดถูกตัดการเชื่อมต่อ


2
แล้วการแก้ไขความขัดแย้งล่ะ ถ้าคนสองคนแก้ไขพื้นที่ข้อความเดียวกันในเวลาเดียวกันล่ะ? นอกจากนี้ดูเหมือนว่าจะวางภาระบนฐานข้อมูลซึ่งเป็นสิ่งที่ OP กำลังมองหาเพื่อหลีกเลี่ยง มันอาจเป็นไปได้สำหรับสิ่งที่เขาต้องการ
Ampt

@Ampt ฉันสร้างสเปรดชีตโดยใช้โมเดลนี้และสำหรับข้อขัดแย้งแต่ละงานที่กำลังอัปเดตนั้นถูกแทนที่ด้วยเวอร์ชันล่าสุดโดยสมบูรณ์ ดังนั้นคนสุดท้ายที่จะแก้ไขเซลล์ให้เสร็จสมบูรณ์จะแทนที่เซลล์ที่อัพเดตก่อนหน้านี้อย่างสมบูรณ์โดยไม่มีการรวม
Korey Hinton

1
ดังนั้นหนึ่งประโยคจะเขียนทับอีกประโยคหนึ่งถ้านี่คือพูดเอกสารคำ?
Ampt

@ ใช่ใช่หรือคุณสามารถใช้วิธีล็อกสิ่งที่กำลังทำงานอยู่ แต่ฉันเลือกเส้นทางที่ง่าย
Korey Hinton

3

1) ดูที่Knockout.js

มันเป็นไปตามรูปแบบ MVVM และจะส่งการแจ้งเตือนไปยังมุมมองโดยอัตโนมัติตามการเปลี่ยนแปลงของโมเดล ตัวอย่างเช่นดูในอาเรย์ที่สามารถสังเกตเห็นได้ของพวกเขาเพื่อให้ข้อมูลเพิ่มเติมเล็กน้อยเกี่ยวกับวิธีการทำเช่นนั้น

2) ผสมที่เข้ากับSignalRและตอนนี้คุณควรมีความสามารถในการส่งการแจ้งเตือนไปยังผู้ใช้รายอื่นที่ทำงานกับเอกสาร จากเว็บไซต์ของพวกเขา:

SignalR ยังมี API ระดับสูงที่ง่ายมากสำหรับการทำเซิร์ฟเวอร์ให้กับลูกค้า RPC (เรียกใช้ฟังก์ชัน JavaScript ในเบราว์เซอร์ของลูกค้าจากรหัส. NET ฝั่งเซิร์ฟเวอร์) ในแอปพลิเคชัน ASP.NET ของคุณรวมถึงการเพิ่ม hooks ที่มีประโยชน์สำหรับการจัดการการเชื่อมต่อ เช่นเชื่อมต่อ / ตัดการเชื่อมต่อเหตุการณ์เชื่อมต่อแบบกลุ่มอนุมัติ

ดังนั้นคุณจะต้องมีตะขอบางอย่างที่ระดับแบบจำลองของคุณภายใน Knockout.js เพื่อทำการโทร SignalR บางครั้งเมื่อมีการเปลี่ยนแปลงเกิดขึ้น ลูกค้าอื่น ๆ จะได้รับการแจ้งจาก SignalR แล้วเรียกการเปลี่ยนแปลงที่สอดคล้องกันในพวกเขาสำเนาของรุ่นซึ่งจะผลักดันกลับขึ้นไปดูของพวกเขา

เป็นการรวมกันที่น่าสนใจของทั้งสองเฟรมเวิร์กและคุณควรจะสามารถค้นหาและรวบรวมข้อมูลเพิ่มเติมเพื่อจัดการกับรายการนั้น ๆ

ตัวอย่างเช่นนี้ตัวอย่างเช่น codeprojectเฉพาะที่อยู่Co Working UIs and Continuous Clientsซึ่งดูเหมือนว่าจะเป็นสิ่งที่คุณกำลังพยายามที่จะทำ

แอปพลิเคชั่นเว็บยุคใหม่อาจต้องนำเสนอประสบการณ์ผู้ใช้ยุคใหม่ - และควรจัดการกับสถานการณ์การทำงานร่วมกันของลูกค้าอย่างต่อเนื่องและเหมาะสม สิ่งนี้เกี่ยวข้องกับการตรวจสอบให้แน่ใจว่าส่วนต่อประสานผู้ใช้กำลังซิงค์ตัวเองอย่างถูกต้องในอุปกรณ์ต่างๆและผู้ใช้ทั่ว ๆ ไป

โพสต์บล็อกนี้ดูเหมือนจะเป็นจุดเริ่มต้นในชุดบทความในบล็อกที่พูดถึงการใช้สองแพคเกจและความแตกต่างที่มีวิธีการ ASP.NET แบบดั้งเดิม อาจให้บางจุดพิจารณาในขณะที่คุณออกแบบเว็บไซต์ของคุณ

โพสต์บล็อกนี้ดูเหมือนจะเป็นพื้นฐานเล็กน้อยและให้พื้นฐานสำหรับการรวมสองแพคเกจ

การเปิดเผยข้อมูล:ฉันไม่ได้มีส่วนเกี่ยวข้องกับลิงก์ใด ๆ ข้างต้นและไม่ได้ขุดเนื้อหาลงในเนื้อหาของพวกเขาเพื่อดูว่าเสียงนั้นถูกต้องหรือไม่


2

การแก้ปัญหาคือการแปลงปฏิบัติการ (OT) หากคุณไม่เคยได้ยินมาก่อน OT เป็นคลาสของอัลกอริธึมที่ทำหลายไซต์พร้อมกันแบบเรียลไทม์ OT เหมือนคอมไพล์เรียลไทม์ มันทำงานได้กับจำนวนความล่าช้าใด ๆ (จากศูนย์ถึงวันหยุดยาว) ช่วยให้ผู้ใช้ทำการแก้ไขสดพร้อมกันกับแบนด์วิดธ์ต่ำ OT ช่วยให้คุณมีความสอดคล้องในที่สุดระหว่างผู้ใช้หลายคนโดยไม่ต้องลองใหม่โดยไม่มีข้อผิดพลาดและไม่มีข้อมูลใด ๆ ถูกเขียนทับ

แต่การใช้งาน OT เป็นงานที่ยากและเสียเวลา ดังนั้นคุณอาจต้องการใช้ห้องสมุดภายนอกเช่นhttp://sharejs.org/


1
Google Realtime API กำลังทำ OT youtu.be/hv14PTbkIs0?t=14m20s พวกเขาทำได้ทั้งบนไคลเอนต์และเซิร์ฟเวอร์ ฉันไม่ได้รับคำตอบที่ชัดเจนจากการอ่านเอกสาร ShareJS แต่ฉันสมมติว่า ShareJS ทำ OT บนไคลเอนต์และเซิร์ฟเวอร์หรือไม่
dev.e.loper

1

ส่วนใหญ่ขึ้นอยู่กับประเภทของเอกสารของคุณและวิธีที่ผู้ใช้ทำงานร่วมกัน

อย่างไรก็ตามฉันจะ:

  1. ให้ลูกค้าทุกคนส่งการเปลี่ยนแปลงที่ไม่ได้บันทึกไปยังเซิร์ฟเวอร์ทุก ๆ ระยะ (ขึ้นอยู่กับวิธีที่ผู้ใช้ทำงานกับเอกสาร)
  2. เซิร์ฟเวอร์จัดเก็บ deltas ในเซสชันของผู้ใช้ (แม้เป็นไคลเอนต์แบบ fat คุณต้องการบางอย่างเช่นเซสชัน)
  3. ลูกค้าอื่น ๆ ที่แก้ไข / ดูเอกสารเดียวกันจะได้รับการเปลี่ยนแปลงชั่วคราวเหล่านั้นหรืออย่างน้อยก็มีคำใบ้ว่าอาจเป็นเช่นนั้น

ข้อดี:

  • ไม่มีการอัพเดทฐานข้อมูลเว้นแต่มีคนคลิก 'บันทึก'
  • สำรองข้อมูลสำหรับกรณีที่ไคลเอนต์ขัดข้อง (สำหรับรอบระยะเวลาเซสชัน)
  • เซิร์ฟเวอร์ของคุณตัดสินใจว่าจะส่งต่อข้อมูลใดไปยังไคลเอนต์ใด (เช่นคุณสามารถข้ามไปเริ่มคุณลักษณะด้วยโน้ตและจากนั้นใช้การผสานและไฮไลต์ที่ซับซ้อนยิ่งขึ้น)

ข้อเสีย:

  • ไม่ใช่ 'เรียลไทม์' - เช่นคุณส่งทุกๆ 30 วินาที แต่บางคนพิมพ์ 3 ประโยคในเวลานั้น
  • เครือข่ายมากขึ้น - ขึ้นอยู่กับเอกสารและการทำงานร่วมกันของคุณ
  • อาจเป็นช่วงที่มีขนาดใหญ่
  • อาจมีความพยายามในการคำนวณสูงหากผู้ใช้หลายคนร่วมมือกันและเปลี่ยนแปลงหลายอย่าง

1

โดยพื้นฐานแล้วสิ่งที่คุณถามคือวิธีจัดการกับสถานะที่ไม่แน่นอนที่แบ่งปัน การออมเป็นส่วนที่ง่าย แต่คุณจะจัดการกับหลาย ๆ คนในการแก้ไขสิ่งเดียวกันในเวลาเดียวกันได้อย่างไร คุณต้องการให้ผู้ใช้ทุกคนกำลังดูเอกสารเดียวกันในขณะที่ทำการซิงโครไนซ์การแก้ไขพร้อมกันทั้งหมดในแบบเรียลไทม์

อย่างที่คุณอาจจะรวบรวมมันเป็นปัญหาที่ยาก! มีวิธีแก้ปัญหาเชิงปฏิบัติไม่กี่:

  1. ปรับเปลี่ยนข้อกำหนดของแอปพลิเคชันของคุณเพื่อไม่อนุญาตการแก้ไขพร้อมกันอย่างแท้จริง การแก้ไขสามารถผสานได้เหมือนกับระบบควบคุมแหล่งที่มาพร้อมผลลัพธ์ที่ถ่ายทอดไปยังไคลเอนต์แต่ละราย คุณสามารถสร้างได้ด้วยตัวเอง แต่มันจะเป็นประสบการณ์การใช้งานที่ไม่ดีนัก
  2. เอาท์ซอร์สการซิงโครไนซ์ของการกลายพันธุ์สถานะกับโซลูชันโอเพนซอร์ซที่รวมเข้ากับเทคโนโลยีที่มีอยู่ของคุณ ShareDBเป็นผู้นำในพื้นที่นี้ มันขึ้นอยู่กับการแปลงปฏิบัติการและใช้ในระบบการผลิตอย่างน้อยหนึ่งระบบ สิ่งนี้จะช่วยจัดการปัญหาการประหยัดที่คุณกังวล แต่จะไม่ช่วยคุณสมบัติเพิ่มเติมใด ๆ ของ UX ที่จำเป็นสำหรับแอปพลิเคชันการทำงานร่วมกัน
  3. ใช้แพลตฟอร์ม off-the-shelf เช่นConvergence (ข้อจำกัดความรับผิดชอบ: ฉันเป็นผู้ก่อตั้ง) เพื่อจัดการกับบิตยาก ๆ ทั้งหมดสำหรับคุณ คุณจะได้รับเครื่องมือเพิ่มเติมสำหรับการทำงานร่วมกันแบบเรียลไทม์เช่นการติดตามเคอร์เซอร์ / เมาส์การเลือกและการแชทเพื่อสร้างประสบการณ์การทำงานร่วมกันที่เหนือกว่าอย่างรวดเร็ว ดูคำถามนี้สำหรับบทสรุปที่ดีของเครื่องมือที่มีอยู่ทั้งหมด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.