Saya memiliki halaman web yang menampilkan sejumlah besar data dari server. Komunikasi dilakukan melalui ajax.
Setiap kali pengguna berinteraksi dan mengubah data ini (Katakanlah pengguna A mengganti nama sesuatu), ia memberitahu server untuk melakukan tindakan dan server mengembalikan data baru yang diubah.
Jika pengguna B mengakses halaman pada saat yang sama dan membuat objek data baru, ia akan kembali memberi tahu server melalui ajax dan server akan kembali dengan objek baru untuk pengguna tersebut.
Di halaman A kami memiliki data dengan objek yang diubah namanya. Dan di halaman B kami memiliki data dengan objek baru. Di server, data memiliki objek yang diganti namanya dan objek baru.
Apa sajakah pilihan saya untuk menjaga halaman tetap sinkron dengan server ketika beberapa pengguna menggunakannya secara bersamaan?
Opsi seperti mengunci seluruh halaman atau membuang seluruh status kepada pengguna pada setiap perubahan agak dihindari.
Jika membantu, dalam contoh khusus ini, halaman web memanggil metode web statis yang menjalankan prosedur tersimpan di database. Prosedur tersimpan akan mengembalikan data apa pun yang telah diubah dan tidak lebih. Metode web statis kemudian meneruskan kembali prosedur tersimpan ke klien.
Bounty Edit:
Bagaimana Anda mendesain aplikasi web multi-pengguna yang menggunakan Ajax untuk berkomunikasi dengan server tetapi menghindari masalah dengan konkurensi?
Yaitu akses bersamaan ke fungsionalitas dan data di database tanpa risiko data atau korupsi negara
Jawaban:
Gambaran:
Hai Raynos,
Saya tidak akan membahas produk tertentu di sini. Apa yang disebutkan orang lain adalah toolset yang bagus untuk dilihat (mungkin tambahkan node.js ke daftar itu).
Dari sudut pandang arsitektur, Anda tampaknya memiliki masalah yang sama dengan yang dapat dilihat pada perangkat lunak kontrol versi. Satu pengguna memeriksa perubahan ke objek, pengguna lain ingin mengubah objek yang sama dengan cara lain => konflik. Anda harus mengintegrasikan perubahan pengguna ke objek sementara pada saat yang sama dapat mengirimkan pembaruan tepat waktu dan efisien, mendeteksi dan menyelesaikan konflik seperti di atas.
Jika saya berada di posisi Anda, saya akan mengembangkan sesuatu seperti ini:
1. Sisi Server:
Tentukan tingkat yang masuk akal di mana Anda akan mendefinisikan apa yang saya sebut "artefak atom" (halaman? Objek di halaman? Nilai di dalam objek?). Ini akan tergantung pada server web Anda, perangkat keras database & cache, # pengguna, # objek, dll. Bukan keputusan yang mudah untuk dibuat.
Untuk setiap artefak atom memiliki:
Komponen server atau pseudo-server yang mampu mengirimkan log perubahan yang relevan ke pengguna yang terhubung secara efisien. Observer-Pattern adalah teman Anda untuk ini.
2. Sisi Klien:
Klien javascript yang dapat memiliki Koneksi HTTP yang berjalan lama ke server tersebut di atas, atau menggunakan polling ringan.
Komponen pembaru artefak javascript yang menyegarkan konten situs saat klien javascript yang terhubung memberi tahu tentang perubahan dalam riwayat artefak yang dipantau. (sekali lagi pola pengamat mungkin merupakan pilihan yang baik)
Komponen pembuat artefak javascript yang mungkin meminta untuk mengubah artefak atom, mencoba memperoleh kunci mutex. Ini akan mendeteksi jika status artefak telah diubah oleh pengguna lain hanya beberapa detik sebelumnya (latan dari klien javascript dan faktor proses komit dalam) dengan membandingkan artefak-versi-id sisi klien yang diketahui dan artefak-versi-id di sisi server saat ini.
Pemecah konflik javascript yang memungkinkan manusia mengambil keputusan yang-ubah-adalah-hak. Anda mungkin tidak ingin hanya memberi tahu pengguna "Seseorang lebih cepat dari Anda. Saya menghapus kembalian Anda. Menangislah.". Banyak opsi dari perbedaan yang agak teknis atau solusi yang lebih ramah pengguna tampaknya memungkinkan.
Jadi bagaimana itu akan bergulir ...
Kasus 1: diagram jenis urutan untuk memperbarui:
Kasus 2: Sekarang untuk melakukan:
Kasus 3: untuk konflik:
Beberapa kata tentang Kinerja & Skalabilitas
Polling HTTP vs. "mendorong" HTTP
penskalaan backend
penskalaan frontend
tweak "kreatif"
Baiklah saya harap ini bisa menjadi awal untuk ide Anda sendiri. Saya yakin ada lebih banyak kemungkinan. Saya lebih dari menyambut kritik atau peningkatan apapun untuk posting ini, wiki diaktifkan.
Christoph Strasen
sumber
Saya tahu ini adalah pertanyaan lama, tetapi saya pikir saya hanya akan setuju.
OT (transformasi operasional) sepertinya cocok untuk kebutuhan Anda untuk pengeditan multi-pengguna secara bersamaan dan konsisten. Ini adalah teknik yang digunakan di Google Docs (dan juga digunakan di Google Wave):
Ada perpustakaan berbasis JS untuk menggunakan Transformasi Operasional - ShareJS ( http://sharejs.org/ ), yang ditulis oleh anggota dari tim Google Wave.
Dan jika Anda mau, ada kerangka kerja web MVC lengkap - DerbyJS ( http://derbyjs.com/ ) dibangun di atas ShareJS yang melakukan semuanya untuk Anda.
Ini menggunakan BrowserChannel untuk komunikasi antara server dan klien (dan saya yakin dukungan WebSockets harus dalam pengerjaan - itu ada di sana sebelumnya melalui Socket.IO, tetapi diambil karena masalah pengembang dengan Socket.io) Dokumen pemula adalah a sedikit jarang saat ini.
sumber
Saya akan mempertimbangkan untuk menambahkan cap yang dimodifikasi berdasarkan waktu untuk setiap dataset. Jadi, jika Anda memperbarui tabel db, Anda akan mengubah stempel waktu yang dimodifikasi. Dengan menggunakan AJAX, Anda dapat membandingkan stempel waktu klien yang dimodifikasi dengan stempel waktu sumber data - jika pengguna tertinggal, perbarui tampilan. Mirip dengan bagaimana situs ini memeriksa pertanyaan secara berkala untuk melihat apakah ada orang lain yang menjawab saat Anda mengetik jawaban.
sumber
Anda perlu menggunakan teknik push (juga dikenal sebagai Comet atau Ajax terbalik) untuk menyebarkan perubahan ke pengguna segera setelah dibuat ke db. Teknik terbaik yang saat ini tersedia untuk ini tampaknya adalah polling panjang Ajax, tetapi tidak didukung oleh setiap browser, jadi Anda perlu fallback. Untungnya sudah ada solusi yang menangani hal ini untuk Anda. Diantaranya adalah: orbited.org dan socket.io yang telah disebutkan.
Di masa depan akan ada cara yang lebih mudah untuk melakukan ini yang disebut WebSockets, tetapi belum pasti kapan standar itu akan siap untuk prime time karena ada masalah keamanan tentang keadaan standar saat ini.
Seharusnya tidak ada masalah konkurensi dalam database dengan objek baru. Tetapi ketika pengguna mengedit objek, server perlu memiliki beberapa logika yang memeriksa apakah objek tersebut telah diedit atau dihapus untuk sementara. Jika objek telah dihapus solusinya, sekali lagi, sederhana: Buang saja hasil edit.
Tetapi masalah yang paling sulit muncul, ketika banyak pengguna mengedit objek yang sama pada waktu yang sama. Jika Pengguna 1 dan 2 mulai mengedit objek pada saat yang sama, mereka berdua akan mengedit data yang sama. Katakanlah perubahan yang dibuat Pengguna 1 dikirim ke server terlebih dahulu saat Pengguna 2 masih mengedit data. Anda kemudian memiliki dua opsi: Anda dapat mencoba menggabungkan perubahan Pengguna 1 ke dalam data Pengguna 2 atau Anda dapat memberi tahu Pengguna 2 bahwa datanya sudah kedaluwarsa dan menampilkan pesan kesalahan kepadanya segera setelah datanya dikirim ke server. Yang terakhir bukanlah pilihan yang sangat ramah pengguna di sini, tetapi yang pertama sangat sulit untuk diterapkan.
Salah satu dari sedikit implementasi yang benar-benar mendapatkan hak ini untuk pertama kalinya adalah EtherPad , yang diakuisisi oleh Google. Saya yakin mereka kemudian menggunakan beberapa teknologi EtherPad di Google Docs dan Google Wave, tapi saya tidak bisa memastikannya. Google juga membuka EtherPad sumbernya, jadi mungkin itu layak untuk dilihat, tergantung pada apa yang Anda coba lakukan.
Benar-benar tidak mudah untuk melakukan hal-hal yang mengedit ini secara bersamaan, karena tidak mungkin melakukan operasi atom di web karena latensi. Mungkin artikel ini akan membantu Anda mempelajari lebih lanjut tentang topik tersebut.
sumber
Mencoba menulis semua ini sendiri adalah pekerjaan besar, dan sangat sulit untuk melakukannya dengan benar. Salah satu opsinya adalah menggunakan kerangka kerja yang dibuat untuk menjaga klien tetap sinkron dengan database, dan satu sama lain, secara realtime.
Saya telah menemukan bahwa kerangka Meteor melakukan ini dengan baik ( http://docs.meteor.com/#reactivity ).
"Meteor menganut konsep pemrograman reaktif. Ini berarti Anda dapat menulis kode Anda dalam gaya imperatif sederhana, dan hasilnya akan dihitung ulang secara otomatis setiap kali ada perubahan data yang bergantung pada kode Anda."
"Pola sederhana ini (komputasi reaktif + sumber data reaktif) memiliki penerapan yang luas. Pemrogram tidak perlu menulis panggilan berhenti berlangganan / berlangganan ulang dan memastikan panggilan tersebut dipanggil pada waktu yang tepat, menghilangkan seluruh kelas kode propagasi data yang jika tidak akan menyumbat Anda aplikasi dengan logika rawan kesalahan. "
sumber
Saya tidak percaya tidak ada yang menyebut Meteor . Ini adalah kerangka kerja baru dan belum matang yang pasti (dan hanya secara resmi mendukung satu DB), tetapi ini membutuhkan semua pekerjaan kasar dan memikirkan aplikasi multi-pengguna seperti yang dijelaskan poster. Faktanya, Anda TIDAK dapat TIDAK membangun aplikasi pembaruan langsung multi-pengguna. Berikut ringkasan singkatnya:
Meteor cukup sederhana sehingga saya sarankan Anda setidaknya melihatnya untuk dicuri ide.
sumber
Halaman Wikipedia ini dapat membantu menambah perspektif untuk belajar tentang konkurensi dan komputasi bersamaan untuk merancang aplikasi web ajax yang menarik atau mendorong pesan peristiwa keadaan ( EDA ) dalam pola pesan . Pada dasarnya, pesan direplikasi ke pelanggan saluran yang menanggapi acara perubahan dan permintaan sinkronisasi.
Ada banyak bentuk perangkat lunak kolaboratif berbasis web secara bersamaan .
Ada sejumlah pustaka klien HTTP API untuk etherpad-lite , editor waktu nyata kolaboratif .
django-realtime-playground menerapkan aplikasi obrolan waktu nyata di Django dengan berbagai teknologi waktu nyata seperti Socket.io .
Baik AppEngine dan AppScale menerapkan API Saluran AppEngine ; yang berbeda dari Google Realtime API , yang ditunjukkan oleh googledrive / realtime-playground .
sumber
Teknik push sisi server adalah cara untuk menuju ke sini. Komet adalah (atau tadinya?) Kata buzz.
Arah tertentu yang Anda ambil sangat bergantung pada tumpukan server Anda, dan seberapa fleksibel Anda / itu. Jika Anda bisa, saya akan melihat socket.io , yang menyediakan implementasi lintas-browser websockets, yang menyediakan cara yang sangat efisien untuk memiliki komunikasi dua arah dengan server, memungkinkan server untuk mendorong pembaruan ke klien.
Secara khusus, lihat ini demonstrasi oleh perpustakaan penulis, yang menunjukkan hampir persis situasi yang Anda gambarkan.
sumber