Autor Zpráva
loping
Profil
Dobrý den,

řeším v rámci projektu situaci, kdy potřebuji zjistit seznam otevřených záložek v prohlížeči. Tj. chtěl bych se zeptat, zdali má otevřená záložka nějaký "name", či je to uloženo v nějakém poli hodnot na které se mohu odkázat??

Děkuji
loping
Beavis
Profil
loping:
To v rámci PHP ani JS nezjistíš.
loping
Profil
Beavis:
děkuji .. zkusím ještě popsat o co mi prakticky jde a co řešíme - nepřepsání si dat, tj.
- pracuji v jedné záložce v aplikaci v určité části - konceptu, kde edituji data ... tj. zde bych si mohl nastavit session o této skutečnosti
- pokud odejdu z této záložky do jiné části aplikace, nechci mít žádnou potvrzující hlášku o tom, že již končím s editací ... tj. změna určité části URL se rovná zrušení sessionu a otevření konceptu pro ostatní, aby mohli editovat
- řešená záležitost - uživatel pracuje v konceptu v jedné záložce - tj. má nastaven session - stejný uživatel však otevře stejný koncept i do druhé záložky a zde řešíme, jak pohlídat, aby ho to již nepustilo

tzn. poslední dvě odrážky řeší situaci, kdy je a kdy se uvolňuje session a to v případech, kdy jednou zůstávám ve stejné záložce a jednou jdu do jiné záložky

no, snad jsem to tak nějak popsal o co mi jde .. tj. proto to řeším :-).

Děkuji za tipy
RastyAmateur
Profil
loping:
A proč ho to nesmí pustit?

Asi bych to řešil tak, že bych každou sekundu (například, klidně minutu, to je na tobě) poslal na server informaci, že data stále edituji. Když by chtěl kdokoliv přijít na tu stránku s editací, zkontroloval bych jen poslední záznam o úpravách a podle toho bych ho tam ne/pustil
loping
Profil
RastyAmateur:
omlouvám se za netypickou konverzaci, ale ať se tu zbytečně dlouho nevymlouvám, tak napíši jak to je ... píši dotaz za programátora, který není zvyklý něco řešit v diskuzích .. tzn. můj nápad byl ten, že on dá dohromady svou otázku a já to vložím sem ... protože jsem dlouho od něj nedostal zadání, tak jsem to svými slovy napsal - viz výše ... nicméně nyní mi již zaslal naformulovaný dotaz, který přidávám .. omlouvám se za toto a prosím o případnou znovureakci ...
DOTAZ: Potřebuji kontrolovat, jestli uživatel otevře odkaz v nové záložce/okně, protože v takovém případě mu chci vypsat hlášku. Pokud ale stránku načte ve stejném okně, tak hlášku vypisovat nepotřebuji. Konkrétně mi jde o to, že uživatel vstoupí do určitého modulu, který jde editovat. V tu chvíli se tento modul zamkne pro přístup jiných uživatelů. Když modul opustí, zase se odemkne. Ale může nastat situace, kdy modul sice opustí tak, že si otevře novou záložku/okno, ale přitom zůstává v první záložce stále přihlášen. V tomto případě potřebuji, aby modul zůstal nadále zamknutý, příp. se hláškou doptat, jestli modul má nebo nemá být odemknut. Existuje nějaký nástroj, jak otevření odkazu v novém okně/záložce prolížeče detekovat?
Keeehi
Profil
loping:
Pro jednoduchost si představme že jde o nějaký redakční systém a uzamykání článků. Budeme mít v databázi tedy nějakou tabulku s články která obsahuje sloupce id_článku, text_článku, zamknuto_uživatelem. Uživatel přijde na stránku edituj-clanek.php?id=8. Script se podívá do databáze a vytáhne řádek d id_článku = 8. V tomto řádku se podívá do sloupce zamknuto_uživatelem. V tomto sloupci je null pokud je článek odemčený nebo id uživatele co ho právě edituje (a je tedy zamčený). Script se tedy podívá na hodnotu sloupce a pokud je tam null, vypíše následně uživateli rozhraní pro editaci článku a záznam v databázi změní tak, že do zamknuto_uživatelem přidá uživatelovo id. Pokud je tam něco jiného, script uživatele odmítne. Dokonce i když tam je stejné číslo jako je id aktuálního uživatele, tak ho script odmítne, jelikož nechcete povolit editaci ve více záložkách.
To by bylo vyřešené zamykání. Článek tedy edituje jen jeden uživatel v jedné záložce. Když je s prací hotov, odešle formulář na script uloz-clanek.php?id=8. Tento script se zase podívá do databáze a vyhledá id_článku = 8. Ověří, že ve sloupci zamknuto_uživatelem je číslo které se shoduje id uživatele. To tam být musí, protože aby člověk mohl takový formulář odeslat musel si ho nejdříve zobrazit a tím tedy daný článek zamkl. Pokud by tam bylo jiné číslo tak článek edituje někdo jiný a toto je nějaký podvodný požadavek a pokud by tam bylo null, tak je to neočekávaný stav systému, který by neměl vzniknout. Takže script ověřil že se zámek shoduje s uživatelem, uloží změnu a do zamknuto_uživatelem uloží null, čímž článek zpřístupní pro další editace. Jak prosté že? Ještě tedy může být script zruseni-editace.php?id=8 který po ověření uživatele jen v databázi nastaví zamknuto_uživatelem na null. Toto by byla reakce na kliknutí na tlačítko zrušit editaci ve formuláři.
Tento systém funguje však jenom v případě, že uživatel co edituje článek vždy na konci tu editaci odešle. A to buď tlačítkem odeslat, nebo zrušit editaci. Problémem pak bude pokud si uživatel stránku zavře, obnoví, atp. V takovém případě se k editaci už nedostane jelikož to byl tvůj požadavek, takže už teď nemůže kliknout na tlačítko zrušit editaci a tím ho odemknout. Takže je potřeba ten systém rozšířit. Pokud by se taková situace stala, uživatel se sice nedostane na konkrétní článek ale stále se dostane na výpis článků. Proto bude potřeba do tohoto výpisu přidat uživateli tlačítka na odemknutí takto uzamčených editací. Jde to velmi jednoduše. Stačí při výpisu těch článků se u každého podívat, jestli v zamknuto_uživatelem je id aktuálního uživatele a pokud ano, tak mu tam přidat i tlačítko s odkazem na zruseni-editace.php?id=id aktuálního článku. Tím se mu objeví tlačítka pro rušení editací/uzamknutí jen u článků, které má sám uzamčené pro editaci.
Takže teď je vyřešená situace, kdy se uživatel sám sebe zamkne. Ovšem vznikla nám tu nová situace. Uživatel si otevře článek 8, tím ho zamkne. Ve vedlejším okně si otevře výpis článků a jelikož je článek 8 zamčený, objeví se mu tam tlačítko pro odemčení tohoto článku. Klikne na něj, tím se článek odemkne. Okno zavře a vrátí se k původnímu formuláři v prvním okně. Ten zedituje a klikne na uložit. V tomto případě se ale dostáváme do situace, kterou jsem popisoval v druhém odstavci jako nedefinovaný stav. V té době byl nedefinovaný, ale to se přidáním toho tlačítka do výpisu článků změnilo, takže teď už definovaný je. Ovšem jelikož se id uživatele neshoduje s null co je v zamknuto_uživatelem, tak se uživateli změny neuloží. Což je správně (nechci tu teď rozebírat proč, už takhle je to dlouhé ale podstatný důvod to má) a uživatel to mohl čekat, když si sám ten zámek ve výpisu článků zrušil.
Teď už je tu jen poslední problém. Uživatel začne s editací článku a pak to prostě nechá viset, prohlížeč zavře a odejde. Nikdo jiný ho nebude moci editovat dokud sám nepřijde na výpis článků a zámek nezruší. To že uživatel zavřel prohlížeč se nedá zjistit, tedy dá ale není to spolehlivé a vrátíme se k tomu později. Takže je potřeba říci si nějakou platnost, po kterou bude zámek platit a pokud to bude více jak daný čas, článek se zase odemkne. Řekněme, že to bude třeba pět minut. Implementace není zase až tak složitá. Do tabulky se přidá sloupec zamknuto_v. Sloupce zamknuto_uživatelem a zamknuto_v se pak vždy vyhodnocují a mění společně. Jakmile se do zamknuto_uživatelem uloží id uživatele, uloží se do zamknuto_v aktuální čas. Kdykoli se kontroluje sloupec zamknuto_uživatelem, nejdříve se zkontroluje zamknuto_v. Pokud je zamknuto_v čas který byl před méně než 5 minutami, použije se hodnota zamknuto_uživatelem. Pokud je tam ale čas starší než 5 minut, bere se jako by v zamknuto_uživatelem bylo null.
Už se blížíme ke konci. Implementovali jsme automatické odemykání, pokud je zámek stačí jak 5 minut. Ovšem to znamená, že uživatel má teď jen 5 minut na editaci. Pokud má zavřený prohlížeč tak to je požadované chování ale pokud má prohlížeč otevřený, chceme ho nechat editovat jak jen dlouho bude chtít. Problém je, že server sám tento stav neumí zjistit. Takže mu to musí prohlížeč sám aktivně hlásit. Bude tedy třeba co 30 vteřin posílat požadavek na adresu heartbeat.php?id=8. Tento script udělá to, že do zamknuto_v (pokud to uživatel stihne v pětiminutovém intervalu) vloží aktuální čas. Tím se vlastně každých 30s nastaví nový 5ti minutový limit, takže to uživateli nikdy nevyprší. Když stránku zavře, není žádný script co by tyto požadavky posílal, tudíž se to po 5 minutách odemkne. Script heartbeat.php pak v odpovědi pošle, jestli se povedlo zámek posunout (stihlo se to do limitu) nebo ne. Je to totiž kvůli tomu, že uživateli mohlo vypadnout připojení k internetu a i když se stránka snažila požadavky posílat na server nic nedorazilo. Mohlo se stát, že v mezidobí než se spojení obnovilo vypršel časový pětiminutový limit, tím se článek odemkl a někdo ho zeditoval. Když se pak spojení obnoví, není už článek není zamčený a není tedy možné ho editovat. V případě tedy neúspěšného prodloužení zámku, je potřeba uživateli zobrazit hlášku, že si má práci někam odzálohovat, jelikož kvůli nečinností (způsobené výpadkem sítě) mu byl zrušen zámek, tudíž nové hodnoty nebudou uloženy a musí začít s editací od začátku.
No a toto je takový malý funkční základ. Velmi podobně to má wikipedie. Dá se to samozřejmě rozšířit. Například stále může nastat situace, že uživatel stránku otevře, nechá ji běžet a nic nedělá. V takovém případě se pořád posílá heartbeat a k uvolnění zámku by nikdy nedošlo. Dá se pak třeba udělat, že stránka odesílá heartbeat jen pokud je aktivní. Dají se na document elementu sledovat eventy jako je click, scroll, touch, keypress, zanamenávat si poslední čas takového eventu a v případě že žádný takový event neproběhl třeba třicet minut (uživatel od počítače pravděpodobně odešel) tak přestat posílat heartbeat. Do pěti minut mu pak zámek vyexpiruje. Případně se dá jeho zámek ukončit rovnou posláním požadavku zruseni-editace.php?id=8. Samozřejmě by se mu zase měla zobrazit hláška, že pro neaktivitu mu byl zrušen zámek a ať si práci odzálohuje.
Druhým rozšířením funkcionality je detekce zavření okna/přechodu na jinou stránku. V pátém odstavci jsem to zmínil a tak se k tomu teď vracím. Pokud se toto rozšíření neimplementuje, tak to nevadí, zámek vyexpiruje po pěti minutách. Pokud se povede zavření okna detekovat, se odemknutí provést ihned. Existují dvě události - onunload a onbeforeunload které se vykonávají těsně před odchodem ze stránky (ať přechodem na jinou stránku nebo zavřením prohlížeče). Pokud je zachytíš, můžeš si v nich poslat požadavek na zruseni-editace.php?id=8 a tím vlastně okamžité odemknutí. Důležité je ale v předchozí větě to slovo pokud. Jde totiž o to, obsluha těchto událostí se provádí těsně před odchodem ze stránky a je tam strašně málo času, takže se nemusí povést ten požadavek odeslat.
To je vše k tomuto způsobu a architektuře která je taková klasická.

S modernějšími technikami jako je například Service Workers lze směr posílání zpráv otočit. V takovém případě může být server aktivním iniciátorem koneverzace, takže stránka nemusí stále posílat heartbeat ale server ji kontaktuje sám až v případě, že to bude potřebovat.
No a pakje tu možnost změnit architekturu a s tím přístup a uvažování. Pokud to chápu správně, tak primárním problémem je že když dva editují současně to samé, aby se neztratila ta informace toho prvního co to uloží tím, že to druhý přepíše. Na to ale není potřeba zamykání. Dá se to řešit historizací. Tedy že daný článek nikdy neupravím ale vždy vytvořím nový záznam a původní označím za neplatný. Pokud tedy někdo bude editovat záznam, do formuláře se mu uloží i číslo verze právě editovaného záznamu. Pokud někdo v průběhu jeho editace ten stejný záznam také upraví, tak to systém při ukládání pozná, protože číslo verze z formuláře se nebude schodovat s číslem aktuálního záznamu. Sytém zná veškerá data, původní verzi, aktuální verzi (ta co někdo upravil) i tu novou, kterou se snaží člověk uložit. Může mu zobrazit všechny tři verze, vyznačit rozdíly a nechat ho, ať to vyřeší. On sloučí své změny s aktuální verzí a uloží takto upravenou verzi, která se stane novou aktuální. Takto nějak to funguje v gitu, takže pokud ty nebo tvůj programátor znáte git, koncept pochopíte velmi rychle. Historizace v databázi pak bude podle SDC 2.
Kajman
Profil
Co to udělat obráceně? Tedy tak, že formulář bude mít jedinečné id. Všechny odkazy na té stránce (vedoucí do stejného webu) mohou mít parametr, že se má nová stránka zeptat, zda formulář s tímto id na staré zachovat.

Všechny odkazy budou mít navěšený onclick, který tento parametr z url odstraní.

Nová stránka otevřená s tímto parametrem se tedy zeptá uživatele, zda chce blokovat formulářem na staré stráce ostatní uživatele. Odpověď se uloží na serveru (asi stačí do session). Stará stránka se periodicky bude ptát serveru, zda formulář s daným id někdo přes hlášku na jiné stránce nezrušil.
Mlocik97
Profil
Keeehi:
Díky že si mi zaplnil mozgovú RAMku.
loping
Profil
moc děkuji za diskuzi .. vše jsem předal programátorovi

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0