Mengikuti respons asli saya , ini lagi-lagi sesuatu di mana beberapa pemikiran berbeda dapat membantu Anda. Dan karena itu, ini tampaknya lebih tentang arsitektur daripada mengatakan bahwa mengimplementasikan kode Anda "dengan cara tertentu" akan menjadi cara terbaik.
Dari komentar Anda tentang itu dan pertanyaan Anda di sini, tampaknya masalah yang perlu Anda selesaikan adalah bagaimana menyesuaikan jumlah pasukan untuk lainnya pengguna memainkan gerakan. Mari kita mulai dengan melihat data yang sama lagi:
{ "_id" : ObjectId("531cf5f3ba53b9dd07756bb7"), "user" : "A", "units" : 50 }
{ "_id" : ObjectId("531cf622ba53b9dd07756bb9"), "user" : "B", "units" : 62 }
Melakukan "gerakan"
Jadi situasi di sini adalah pengguna "B" baru saja bergerak dan melakukan 62
unit dalam gerakan itu. Dalam posting sebelumnya saya menjelaskan cara mendapatkan kembali langkah untuk pengguna yang cocok "A", dan oleh karena itu Anda dapat "menyandingkan" mereka dan menentukan kemenangan.
Mengambil itu lebih jauh, pertimbangkan apa yang terjadi dalam permintaan. Pengguna "B" mengajukan, lalu Anda memasukkan dokumen untuk langkah mereka, lalu Anda membaca kembali yang cocok. Jadi sekarang Anda memiliki kedua dokumen dalam memori untuk permintaan tersebut. Jika Anda mempertimbangkan data sesi, maka Anda mungkin memiliki sesuatu seperti ini (dalam cara yang sangat singkat):
{
currentUnits: 100
}
Sebut saja itu hitungan awal. Jadi saat Anda mengirim langkah dari pengguna, Anda hanya mengurangi jumlah pasukan yang mereka miliki. Jadi saat melakukan menyisipkan dari 62
pasukan, counternya begini:
{
currentUnits: 38
}
Itu praktik yang baik, seperti yang Anda lakukan pada pengakuan sisipan saat bergerak. Tapi selanjutnya di dalam panggilan balik itu Anda akan melakukan pencarian seperti yang saya katakan, dan itu hanya mengembalikan satu dokumen. Sekarang Anda memiliki informasi yang dapat Anda bandingkan dan hitung. Pengguna "B" menang sehingga Anda dapat menyesuaikan nilai sesi Anda:
{
currentUnits: 150
}
Jadi itu harus mencakup semuanya untuk perpindahan untuk pengguna "B". Anda mengambil unit ketika sebuah gerakan dimainkan, Anda mencocokkan pemain lain, lalu Anda "menghitungnya" dan menyesuaikan hasil Anda. Selesai! Oh, dan Anda telah menyimpan semua data sesi di toko persisten bukan? Mengangguk ya. Dan juga data sesi tersebut diikat ke pegangan pengguna (atau pengguna sebenarnya adalah id sesi) untuk mendapatkan akses untuk memodifikasinya.
Yang tersisa hanyalah "memberi tahu" pemain lain.
Memberitahukan berita kepada orang lain
Bagian ini harus sederhana. Jadi saya tidak mengkodekannya untuk Anda. Anda menggunakan socket.io untuk aplikasi Anda, jadi semua ini adalah mengirim pesan. Itu berarti data yang Anda "pancarkan" memberi tahu pengguna lain di klien bahwa mereka "kehilangan pasukan", bagaimanapun Anda ingin menghadapinya. Tapi ingat juga bahwa Anda "mengambil" unit-unit itu saat mereka pindah telah diserahkan. Dalam semua kasus yang memastikan tidak ada yang bisa melakukan lebih dari yang mereka lakukan.
Satu-satunya hal yang mungkin untuk dibicarakan di sini adalah skala aplikasi Anda di luar satu contoh. Jadi, Anda dapat berbicara dengan gembira dengan acara di "node" yang semuanya bekerja pada satu instance server, tetapi untuk "menskalakan" Anda perlu meneruskan pesan di antara instance yang berbeda.
Salah satu cara untuk menangani ini menggunakan MongoDB adalah dengan koleksi yang dibatasi .
Selain dari apa yang biasanya dilakukan oleh koleksi yang dibatasi dalam cara menyimpan set ukuran untuk kumpulan dokumen, ada satu hal lagi yang mereka tawarkan, dan itu adalah kursor tailable . Cara yang cukup umum untuk membuatnya dengan driver node adalah seperti:
var options = { tailable: true, awaitdata: true, numberOfRetries: -1 };
var cursor = collection.find(query, options).sort({ $natural: 1 });
Opsi lengkap tercantum di Cursor() bagian dari halaman manual driver. Anda bisa mendapatkan metode "asli" ini di luwak dengan cara biasa.
Apa yang dilakukan kursor "tailable" adalah untuk "mengikuti" dokumen "terakhir disisipkan" dalam koleksi dan Anda dapat duduk dan "mengikuti" dengan cara ini dengan polling yang genap, seperti di:
(function more() {
cursor.nextObject(handle(function(doc) {
if (!doc) return setTimeout(poll, self.wait);
callback(doc);
latest = doc._id;
more();
}));
})();
Jadi dalam konstruksi seperti itu Anda "menemukan" dokumen yang baru dimasukkan dan meneruskan ke panggilan balik batin Anda informasi untuk diproses, di mana Anda "mengirim" pesan ke klien, memperbarui berbagai hal, dan apa pun yang ingin Anda lakukan.
Kembali ke "permintaan" Anda yang sebenarnya, maka Anda akan mengeluarkan sisipan setelah Anda "melakukan perhitungan" ke "koleksi tertutup" yang terpisah. Anda ingin sesuatu yang bermakna dengan singkat seperti:
{ "player": "B", "vsplayer": "A", "win": 50, "loss": 62 }
Dan sekali lagi ini hanya sisipan. Jadi, Anda akan menyiapkan indeks TTL untuk menangani penghapusan dari waktu ke waktu dan dibatasi, entri lama secara alami akan terkuras dengan "didorong keluar" dari entri yang ada dalam koleksi.
Di sisi "klien" Anda, setiap aplikasi pengguna yang terhubung melacak nilai "last _id" yang diterima. Jadi entri yang baru dimasukkan selalu lebih besar nilainya dari yang "lebih tua" sebelumnya.
Jadi ada "satu cara" untuk menggunakan MongoDB untuk membuat antrian persisten yang dapat Anda proses secara berurutan untuk berbagi pesan yang lewat di antara beberapa instance server aplikasi.
Kata Akhir
Dengan semua yang dikatakan untuk menerapkan kursor "bisa ekor" dengan cara ini, untuk uang saya, saya akan menggunakan zeromq atau sesuatu yang mirip. Tetapi Anda mungkin menemukan metode MongoDB lebih cocok untuk Anda jika Anda tidak ingin mempelajari teknologi lain. Atau mungkin "skalabilitas" semacam ini tidak diperlukan oleh aplikasi Anda (setidaknya pada tahap ini) dan hanya meneruskan ke metode "socket.io" dalam permintaan sudah cukup. Terserah Anda.
Namun, sebagian besar, Anda tampaknya masih "tertutup" pada konsep Anda tentang "mengupas" dan "menghapus". Ini adalah niat untuk menutupi dalam tanggapan terakhir dan mengatakan bahwa menghapus dokumen saat diproses tidak diperlukan . Proses yang dijelaskan memastikan bahwa Anda tidak pernah mendapatkan "pasangan yang sama" kembali atas permintaan apa pun.
Saya akan mendorong Anda untuk "membaca ulang" informasi itu dan benar-benar memahami prosesnya. Dan tanyakan jika Anda memiliki pertanyaan. Dari apa yang telah dibahas di sana, analogi pola akses data Anda lebih seperti "bermain tumpukan" daripada "pasangan yang cocok".
Jadi apa yang Anda berikan sebagai tanggapan, mengikuti dengan logika yang dijelaskan di sini adalah semua Anda perlukan untuk mengatur pola akses data Anda. Komponen Anda yang lain tentu saja adalah perpesanan, tetapi ini memberi Anda akses ke data yang Anda butuhkan.