Bagaimana cara menyimpan selama kolaborasi waktu nyata

10

Saya ingin banyak pengguna mengedit dokumen yang sama. Masalah yang saya hadapi adalah ketika pengguna baru bergabung, ia mungkin melihat dokumen yang sudah usang. Bagaimana cara memastikan bahwa pengguna baru mendapatkan perubahan terbaru?

Beberapa solusi yang saya pikirkan:

  • Simpan di setiap perubahan. Saya tidak suka solusi ini karena ini akan memperlambat segalanya pada UI dan memuat db.

  • Ketika pengguna baru bergabung, memicu save pada semua klien lain. Setelah klien lain disimpan, muat dokumen. Dengan ini masih ada ketidakkonsistenan.

Saran lain akan sangat membantu.

UPDATE: Setelah melihat ke solusi yang disarankan, Google Realtime API, saya menemukan bahwa:

  1. Pengguna aplikasi Anda harus memiliki Google Drive dan memberi Anda akses ke drive mereka . Paling-paling ini bisa menghadirkan aliran UI yang canggung atau mencegah pengguna yang tidak memiliki Google Drive menggunakan fitur waktu nyata.

  2. Semua pengaturan berbagi yang dilakukan di pihak Anda, harus direplikasi untuk dokumen Google.

PEMBARUAN 2: Untuk mencapai tujuan, saya menggunakan Firebase Google

dev.e.loper
sumber
Mengapa ada perbedaan antara pengguna baru dan pengguna yang sudah aktif mengedit / melihat dokumen yang sama?
Andy
@Andy Apa yang saya lakukan saat ini adalah menyiarkan melalui soket semua perubahan yang dilakukan pengguna. Perubahan ini memperbarui UI untuk pengguna yang browsernya terbuka tetapi tidak langsung disimpan ke basis data. Jadi saya punya situasi, ketika pengguna baru bergabung, dia memuat dokumen dari database dan dia tidak melihat semua perubahan terbaru yang belum disimpan.
dev.e.loper
1
jika Anda sudah mengirim perubahan, dan ingin meninggalkan perilaku yang sama seperti sekarang, Anda dapat meminta salah satu klien mengirim tampilan terakhir ke klien baru atau Anda dapat memiliki satu klien virtual di server, yang mendapatkan semua perubahan dan ketika klien baru bergabung mengirim terbaru lihat itu.
Dainius

Jawaban:

14

google Drive

Jika Anda mencoba membuat versi google docs Anda sendiri, saya sarankan Anda melihat Google Realtime API . Google baru-baru ini merilis ini dengan maksud memungkinkan pengembang lain untuk menggunakan alat yang sama yang mereka lakukan untuk memungkinkan kolaborasi waktu nyata. Ini akan memungkinkan Anda untuk menghemat waktu pada pengembangan Anda dan mendapatkan produk yang bekerja lebih cepat.

Anda dapat dengan mudah mengambil data yang ada di dokumen dan mendorongnya ke dalam basis data Anda secara berkala, atau menjadikan basis data itu sendiri menjadi 'peserta' dari pertukaran tersebut, cukup mendengarkan dan mencatat semua perubahan. Hal ini juga memungkinkan bagi pengguna untuk menentukan struktur data mereka sendiri yang kemudian dapat digunakan dalam API waktu nyata, sehingga Anda bebas untuk memperpanjangnya sesuai keinginan Anda.

Non-Google Drive

Jadi menurut penelitian Anda, Google Drive bukan pilihan. Tidak apa-apa, tapi itu akan lebih sulit dan mungkin tidak bekerja juga, tergantung pada seberapa banyak Anda memasukkannya ke dalamnya.

Inilah strategi umum yang akan saya gunakan untuk menyelesaikan masalah ini:

  1. Biarkan server menjadi multiplexer komunikasi. Setiap orang berbicara ke server, dan server mengirimkan informasi itu kepada orang lain. Dengan cara ini server selalu memiliki tampilan dokumen yang paling mutakhir.

  2. Temukan algoritma / modul pihak ketiga untuk resolusi konflik. Resolusi konflik itu sulit, dan merupakan sesuatu yang masih belum sempurna. Melakukan ini sendiri dapat dengan mudah meningkatkan ruang lingkup proyek menjadi terlalu besar. Jika Anda tidak dapat menggunakan algoritme pihak ketiga, saya menyarankan agar Anda hanya mengizinkan satu pengguna untuk mengedit area waktu, sehingga pengguna harus mendapatkan kunci sebelum mengedit area, atau Anda berisiko menghancurkan pekerjaan pengguna lain, yang akan menjadi sangat tua, sangat cepat.

  3. Ketika pengguna baru bergabung, berikan mereka dokumen terbaru dan secara otomatis mulai streaming perintah kepada mereka. Server memiliki tampilan terbaru dan dengan demikian dapat menyajikannya secara otomatis.

  4. Cadangkan ke database pada interval tertentu. Putuskan seberapa sering Anda ingin mencadangkan (setiap 5 menit atau mungkin setiap 50 perubahan.) Ini memungkinkan Anda untuk mempertahankan cadangan yang Anda inginkan.

Masalah: Ini bukan solusi yang sempurna, jadi inilah beberapa masalah yang mungkin Anda hadapi.

  1. Throughput server dapat menghambat kinerja

  2. Terlalu banyak orang membaca / menulis dapat membebani server

  3. Orang-orang mungkin menjadi tidak sinkron jika ada pesan yang hilang, jadi Anda mungkin ingin memastikan Anda melakukan sinkronisasi pada titik-titik reguler. Ini berarti mengirimkan seluruh pesan lagi, yang bisa mahal, tetapi kalau tidak orang mungkin tidak memiliki dokumen yang sama dan tidak mengetahuinya.

Ampt
sumber
Ya, perubahan disiarkan ke semua klien dan mereka memiliki versi mereka (semoga sama) di browser. Kedengarannya seperti Anda mengatakan bahwa, memperbarui dokumen pada setiap tindakan, adalah cara untuk melangkah?
dev.e.loper
Atau setidaknya memiliki kerangka waktu 'sinkronisasi' yang teratur di mana keadaan dokumen saat ini dikirim di latar belakang untuk memastikan bahwa semua orang berada di halaman yang sama. Seberapa sering tergantung pada seberapa cepat orang akan mengubah dokumen. Dengan begitu Anda sudah memiliki metode yang mapan untuk mengirim ke orang baru, serta kemampuan untuk memastikan itu tidak pernah menyimpang terlalu banyak.
Ampt
1
+1. Jangan membuat hidup menjadi sulit. Google melakukan ini dengan baik tanpa harus menemukan kembali kemudi.
Neil
Apakah Google Realtime menyimpan ke Google Drive? Saya ingin menyimpan ke database saya, bukan Google Drive.
dev.e.loper
@ dev.e.loper menambahkan beberapa info tentang itu ke jawaban untuk Anda.
Ampt
3

Saya akan merekomendasikan 1 salinan dokumen yang persisten di server. Ketika klien terhubung ke server Anda mengeluarkan UPDATEperintah ke klien dengan semua perubahan.

Perbarui WorkFlow

Pengguna menyebabkan pemicu perubahan -> Klien mengirim UPDATEke Server -> Server mengirim UPDATEke Klien

Pemicu yang layak

  1. Klik pengguna Simpan
  2. Pengguna menyelesaikan tugas tertentu
    • Selesai mengedit sel
    • Selesai mengedit kalimat / paragraf / baris
  3. Pengguna mengklik Undo
  4. Pengguna menekan tombol Return
  5. Pengguna mengetikkan kunci (simpan di setiap perubahan)

Perbarui Implementasi

Saya menyarankan untuk dapat membuat kembali dokumen dengan serangkaian UPDATEperintah sehingga server menyimpan setiap UPDATE dan ketika klien baru menghubungkan klien dapat dikirim serangkaian pembaruan dan itu sendiri dapat membuat kembali dokumen untuk ditampilkan ke pengguna. Selain itu, Anda juga dapat memiliki SAVEperintah yang terpisah dan memiliki UPDATE sebagai perubahan sementara yang dapat digunakan untuk UNDOpermintaan dan memiliki SIMPAN sebenarnya menyimpannya untuk dibuka kembali jika server ditutup atau semua klien memutuskan sambungan.

Korey Hinton
sumber
2
Bagaimana dengan resolusi konflik? Bagaimana jika dua orang mengedit area teks yang sama secara bersamaan? Juga, ini tampaknya menempatkan beban pada DB, yang merupakan sesuatu yang OP ingin hindari. Mungkin layak untuk apa yang dia butuhkan.
Ampt
@Ampt Saya membuat spreadsheet menggunakan model ini, dan untuk konflik setiap tugas tertentu yang diperbarui sepenuhnya digantikan oleh versi terbaru. Jadi orang terakhir yang menyelesaikan pengeditan sel akan menggantikan yang diperbarui sebelumnya sepenuhnya tanpa penggabungan.
Korey Hinton
1
Jadi satu kalimat akan menimpa yang lain jika ini, katakanlah, sebuah dokumen kata?
Ampt
@Ampt ya, atau Anda bisa menerapkan cara mengunci apa yang sedang dikerjakan, tapi saya mengambil rute yang mudah.
Korey Hinton
3

1) Lihatlah Knockout.js

Ini mengikuti pola MVVM dan secara otomatis akan mendorong pemberitahuan ke Tampilan berdasarkan perubahan pada Model. Sebagai contoh, lihatlah array mereka yang dapat diamati untuk memberikan sedikit informasi lebih banyak tentang bagaimana mereka melakukan itu.

2) Campurkan dengan SignalR dan Anda sekarang harus memiliki kemampuan untuk mengirimkan pemberitahuan kepada pengguna lain yang mengerjakan dokumen. Dari situs mereka:

SignalR juga menyediakan API tingkat tinggi yang sangat sederhana untuk melakukan RPC server ke klien (panggil fungsi JavaScript di browser klien Anda dari kode .NET sisi-server) di aplikasi ASP.NET, serta menambahkan kait yang berguna untuk manajemen koneksi , mis. menghubungkan / memutus acara, mengelompokkan koneksi, otorisasi.

Jadi, Anda harus memiliki beberapa kait di tingkat model Anda di dalam Knockout.js untuk melakukan beberapa panggilan SignalR setiap kali terjadi perubahan. Klien lain akan menerima pemberitahuan dari SignalR dan kemudian memicu perubahan yang sesuai dalam mereka salinan Model, yang akan mendorong kembali ke View mereka.

Ini kombinasi yang menarik dari dua kerangka kerja, dan Anda harus dapat mencari dan mengumpulkan lebih banyak informasi untuk menangani rincian.

Sebagai contoh, contoh proyek ini secara khusus membahas alamat Co Working UIs and Continuous Clientsyang tampaknya persis seperti apa yang Anda coba lakukan.

Aplikasi web zaman baru mungkin perlu menawarkan pengalaman pengguna zaman baru - dan harus menangani skenario klien yang bekerja bersama dan terus menerus. Ini melibatkan memastikan bahwa antarmuka pengguna menyinkronkan dirinya sendiri dengan baik di seluruh perangkat dan di seluruh pengguna untuk memastikan keadaan aplikasi dan antarmuka pengguna dipertahankan "sebagaimana adanya".

Posting blog ini tampaknya menjadi titik masuk ke dalam serangkaian posting blog yang membahas penggunaan dua paket dan kontras dengan pendekatan ASP.NET tradisional. Dapat memberikan beberapa poin untuk dipertimbangkan saat Anda merancang situs Anda.

Posting blog ini tampaknya sedikit lebih mendasar dan memberikan dasar untuk menggabungkan dua paket.

Pengungkapan: Saya tidak berafiliasi dengan salah satu tautan di atas, saya juga belum benar-benar menggali konten mereka untuk melihat seberapa suaranya atau memperbaikinya.


sumber
2

Solusinya adalah Operational Transformation (OT). Jika Anda belum pernah mendengarnya, OT adalah kelas algoritme yang melakukan konkurensi waktu-nyata multi-situs. OT seperti git realtime. Ini berfungsi dengan jumlah lag apa pun (dari nol hingga liburan panjang). Ini memungkinkan pengguna melakukan pengeditan langsung dan berbarengan dengan bandwidth rendah. OT akhirnya memberi Anda konsistensi antara beberapa pengguna tanpa coba lagi, tanpa kesalahan dan tanpa ada data yang ditimpa.

Tetapi menerapkan PL adalah tugas yang sulit dan memakan waktu. Jadi, Anda mungkin ingin menggunakan perpustakaan eksternal seperti http://sharejs.org/ .

aj_
sumber
1
Google Realtime API melakukan PL youtu.be/hv14PTbkIs0?t=14m20s Mereka melakukannya pada klien dan server. Saya tidak bisa mendapatkan jawaban yang jelas dari membaca dokumen ShareJS tapi saya berasumsi bahwa ShareJS melakukan OT pada klien dan server?
dev.e.loper
1

Ini terutama tergantung pada jenis dokumen Anda dan bagaimana pengguna Anda berkolaborasi.

Namun, saya akan:

  1. biarkan semua klien mengirim perubahan yang belum disimpan ke server sesekali (tergantung pada bagaimana pengguna bekerja dengan dokumen).
  2. server menyimpan delta di sesi pengguna (bahkan untuk klien gemuk Anda perlu sesuatu seperti sesi)
  3. klien lain yang mengedit / melihat dokumen yang sama mendapatkan perubahan sementara atau setidaknya petunjuk bahwa mungkin ada.

Keuntungan:

  • tidak ada pembaruan DB kecuali seseorang mengklik 'simpan'
  • backup untuk kasing klien (untuk sesi-periode)
  • server Anda memutuskan bagaimana dan data apa yang akan diteruskan ke klien mana (misalnya Anda dapat langsung memulai fitur hanya dengan catatan dan kemudian menerapkan penggabungan dan sorotan yang lebih canggih)

Kekurangan:

  • bukan 'waktu nyata' - mis. Anda mengirim setiap 30 detik, tetapi seseorang mengetik 3 kalimat pada saat itu.
  • lebih banyak lalu lintas jaringan - tergantung pada dokumen dan kolaborasi Anda
  • mungkin sesi besar
  • mungkin upaya komputasi tinggi jika banyak pengguna berkolaborasi dan melakukan banyak perubahan
Andy
sumber
1

Pada dasarnya, yang Anda tanyakan adalah bagaimana menghadapi keadaan yang bisa berubah yang dibagikan bersama. Menabung adalah bagian yang mudah; tetapi bagaimana Anda berurusan dengan banyak orang yang mengedit hal yang sama pada saat yang sama? Anda ingin semua pengguna melihat dokumen yang sama saat menyinkronkan pengeditan simultan, semuanya dalam waktu nyata.

Seperti yang mungkin sudah Anda kumpulkan, ini masalah yang sulit! Ada beberapa solusi pragmatis:

  1. Ubah persyaratan aplikasi Anda agar tidak memungkinkan pengeditan simultan yang sebenarnya. Pengeditan dapat digabung seperti dengan sistem kontrol sumber, dengan hasil yang disiarkan ke setiap klien. Anda dapat membuat ini sendiri tetapi itu akan menjadi pengalaman pengguna yang lebih buruk.
  2. Mengalihdayakan sinkronisasi mutasi negara ke solusi open-source yang terintegrasi dengan teknologi Anda yang ada. ShareDB adalah pemimpin saat ini di ruang ini. Ini didasarkan pada Transformasi Operasional dan digunakan dalam setidaknya satu sistem produksi. Ini akan menangani masalah penghematan yang Anda khawatirkan tetapi tidak akan membantu dengan fitur UX tambahan yang wajib untuk aplikasi kolaboratif apa pun.
  3. Gunakan platform off-the-shelf seperti Convergence (penafian: Saya seorang pendiri) untuk menangani semua bagian yang sulit bagi Anda. Anda juga akan mendapatkan alat tambahan untuk kolaborasi waktu nyata seperti pelacakan kursor / mouse, pilihan, dan obrolan untuk membangun pengalaman kolaboratif yang unggul dengan cepat. Lihat pertanyaan ini untuk pengumpulan yang baik dari semua alat yang ada di luar sana.
alalonde
sumber