V návaznosti na moji původní odpověď , to je zase něco, kde vám může pomoci jiné myšlení. A jako takové se zdá, že jde spíše o architekturu než o tvrzení, že implementace vašeho kódu „určitým způsobem“ bude nejlepší způsob, jak jít.
Z vašeho komentáře a vaší otázky zde se zdá, že problém, který potřebujete vyřešit, je, jak upravit počet vojáků pro ostatní uživatel hraje tah. Začněme tím, že se znovu podíváme na stejná data:
{ "_id" : ObjectId("531cf5f3ba53b9dd07756bb7"), "user" : "A", "units" : 50 }
{ "_id" : ObjectId("531cf622ba53b9dd07756bb9"), "user" : "B", "units" : 62 }
Udělejte "tah"
Situace je tedy taková, že uživatel "B" právě provedl svůj pohyb a zavázal se 62
jednotky v tomto tahu. V předchozím příspěvku jsem vysvětlil, jak získat zpět tah pro odpovídající uživatele "A", a proto je můžete "spárovat" a určit výhru.
Když to vezmete dále, zvažte, co se stalo v žádosti. Uživatel "B" odeslal, pak vložíte dokument pro jeho přesun a poté si přečtete odpovídající. Takže právě teď máte oba dokumenty v paměti pro žádost. Pokud vezmete v úvahu data relace, můžete mít něco takového (ve velmi stručné podobě):
{
currentUnits: 100
}
Říkejme tomu počáteční počet. Když tedy odešlete tah od uživatele, stačí snížit počet vojáků, které mají. Takže když děláte vložení z 62
vojáků, počítadlo jde na toto:
{
currentUnits: 38
}
To je dobrá praxe, protože to děláte na potvrzení vložení během tahu. Ale příště uvnitř toho zpětného volání provedete nález, jak jsem řekl, a to pouze vrátí jeden dokument. Nyní máte informace, které můžete porovnávat a počítat. Uživatel "B" vyhrává, takže můžete upravit hodnotu relace:
{
currentUnits: 150
}
To by tedy mělo pokrýt vše pro přesun pro uživatele „B“. Odebrali jste jednotky, když se hrál tah, dorovnali jste druhého hráče, pak jste „spočítali“ a upravili své výsledky. Hotovo! Jo a ušetřili všechna data relace v trvalém úložišti, že? Přikývnout ano. A také, že data relace jsou svázána s uživatelským popisovačem (nebo uživatel je ve skutečnosti id relace), aby bylo možné je upravit.
Jediné, co zbývá, je "upozornit" druhého hráče.
Řekněte novinky někomu jinému
Tato část by měla být jednoduchá. Takže vám to nekóduji. Používáte socket.io pro vaši aplikaci, takže vše, co se týká, je odeslání zprávy. To znamená, že data, která „vyšlete“, sdělují druhému uživateli na klientovi, že „přišel o své jednotky“, ať už se s tím chcete vypořádat. Pamatujte ale také na to, že jste tyto jednotky „odnesli“, když jejich pohyb byla předložena. Ve všech případech to znamená, že nikdo nemůže spáchat více, než má.
Jediné, o čem se zde dá mluvit, je škálování vaší aplikaci nad rámec jedné instance. Můžete tedy vesele hovořit s událostmi na „uzlu“, které všechny fungují na jedné instanci serveru, ale pro „škálování“ byste museli předávat zprávy mezi různými instancemi.
Jedním ze způsobů, jak to zvládnout pomocí MongoDB, může být omezené kolekce .
Kromě toho, co limitované kolekce obecně dělají ve způsobu udržování množiny velikost pro sbírku dokumentů, je tu ještě jedna věc, kterou nabízejí, a to je tabulkový kurzor . Poměrně atypický způsob vytvoření s ovladačem uzlu by byl:
var options = { tailable: true, awaitdata: true, numberOfRetries: -1 };
var cursor = collection.find(query, options).sort({ $natural: 1 });
Úplné možnosti jsou uvedeny v Cursor() části manuálové stránky ovladače. K těmto "nativním" metodám se v mongoose dostanete typickým způsobem.
„Tabulkový“ kurzor je nastaven tak, aby „sledoval“ „naposledy vložený“ dokument ve sbírce a můžete sedět a „sledovat“ tímto způsobem s rovnoměrným hlasováním, podobně jako v:
(function more() {
cursor.nextObject(handle(function(doc) {
if (!doc) return setTimeout(poll, self.wait);
callback(doc);
latest = doc._id;
more();
}));
})();
Takže v rámci takového konstruktu „najdete“ nově vložený dokument a předáte svému vnitřnímu zpětnému volání informace ke zpracování, kde „posíláte“ zprávy klientům, aktualizujete věci a cokoli jiného, co chcete dělat.
Zpět k vaší skutečné "žádosti", pak byste vystavili přílohu poté, co jste "spočítali" do samostatné "limitované kolekce". Chtěli byste něco smysluplného ve zkratce jako:
{ "player": "B", "vsplayer": "A", "win": 50, "loss": 62 }
A to jsou opět jen vložky. Takže byste nastavili TTL index aby se zvládlo mazání v průběhu času a byly omezeny, staré položky by se přirozeně vyčerpaly tím, že by byly "vytlačeny" z položek přítomných ve sbírce.
Na straně vašeho „klienta“ každá připojená uživatelská aplikace sleduje obnovenou hodnotu „posledního _id“. Nově vložené položky jsou tedy vždy větší hodnotu než „starší“ předchozí.
Existuje tedy „jeden způsob“ použití MongoDB k vytvoření trvalé fronty, kterou můžete postupně zpracovávat za účelem sdílení předávání zpráv mezi více instancemi aplikačního serveru.
Poslední slova
Se vším, co bylo řečeno pro implementaci "tail-schopného" kurzoru tímto způsobem, za své peníze bych používal zeromq nebo něco podobného. Ale možná zjistíte, že metoda MongoDB je pro vás vhodnější, pokud se nechcete ponořit do jiné technologie. Nebo možná vaše aplikace tento druh "škálovatelnosti" nepotřebuje (alespoň v této fázi) a stačilo by jednoduše předat metody "socket.io" v rámci požadavku. Je to na vás.
Z velké části se však stále zdá, že jste „zavěšeni“ na svých konceptech „párování“ a „mazání“. Toto bylo záměrem pokrýt v poslední odpovědi a chtělo to říci mazání dokumentů při jejich zpracování není vyžadováno . Popsaný proces zajišťuje že nikdy nedostanete "stejný pár" zpět na jakoukoli žádost.
Doporučuji vám přečíst si znovu tyto informace a skutečně porozumět procesu. A ptejte se, pokud máte otázky. Z toho, co zde bylo diskutováno, je analogie vašeho vzoru přístupu k datům spíše jako „přehrávání hromady“ než „párování párů“.
Takže to, co jste dostali jako odpověď, následovat se zde popsanou logikou je vše byste měli potřebovat k nastavení vzorů přístupu k datům. Vaší další součástí bude samozřejmě zasílání zpráv, ale to vám dává přístup k datům, která potřebujete.