Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

onunload i.c.m. xmlhttprequest

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik maak een tool voor binnen ons bedrijf, waarmee verschillende mensen tegelijk gaan werken. De werkvoorraad zit in een MySQL-database. Ik heb nu bedacht dat, als iemand een record opvraagt, de status van deze record aan wordt gepast. De status is gewoon een veldje dat 0 (onbehandeld), 1 (in behandeling), 2 (afgehandeld) kan zijn. PHP/MySQL schotelt de gebruiker simpelweg de oudste record met status 0 voor.

Stel nu dat iemand een record opvraagt. De status wort dan op 1 gezet. Als deze persoon zijn werk niet afmaakt en zijn browser sluit (of een andere pagina opent), dan blijft de status dus op 1 staan. Het leek me dus handig om met een onunload een xmlhttprequest te doen naar een php-pagina, die de status terug op 0 zet.

Dit werkt alleen niet. Mijn php-file werkt en als ik de xmlhttprequest-functie aanroep met een onclick gaat het wel goed. Het zit 'm dus in de onunload. Ik heb ook al onbeforeunload geprobeerd.

Het gaat er mij om, dat mijn php-pagina wordt aangeroepen en dat een id-nummer wordt meegestuurd. Ik hoef geen feedback of zoiets te hebben van de php-pagina.

Ik test het hier met FF2 op mijn Mac. (Het moet werken op FF, Safari, IE6 en IE7.)

Nu gok ik dat de xmlhttprequest wordt afgebroken bij het wachten op respons of ziets. Ik heb het geprobeerd met POST en met GET. Ik heb async op true staan.

Iemand een idee?

Verwijderd

Dit hele ontwerp klopt gewoon niet. Het "locken" van records mag best worden aangevraagd door een client. Maar het unlocken ervan zal toch echt ook vanaf de server geregeld moeten worden.

Je zou het ongekeerde kunnen doen. Stel je update elke x minuten het tijdstip dat een record gelockt is. Als iemand dan een record opvraagt, mag deze niet minder dan y minuten gelockt zijn.

Op deze manier is een bestand nooit meer dan y minuten gelockt als hij niet meer wordt bekeken/bewerkt door de originele eigenaar van de lock. En als de locker het record heeft aangepast of gesloten kun je de lock meteen verwijderen, net als anders.

  • rhodium
  • Registratie: Augustus 2003
  • Laatst online: 15-11 22:20
Ik denk dat je beter hiervoor met een time-out systeem kan werken. De xmlhttprequest stuurt bijvoorbeeld om de minuut een php bestaand die er voor zorgt dat timestamp in je database wordt geupdate van de betreffende werk-item.

Je kunt de time-out ook naar 10sec zetten als het systeem erg veel gebruikt wordt..

idee?

  • Rowdy.nl
  • Registratie: Juni 2003
  • Laatst online: 28-11 14:33

Rowdy.nl

Koekje d'r bij?

Zoals hierboven... In dit geval zou iemand die Javascript uit zet, of gewoon zijn pc afsluit zonder de browsers eerst af te sluiten, de browser van crasht, de stekker uit zijn pc schopt....... een record voor altijd locken...

Een sessie binnen PHP kent altijd een time out, dus na een x aantal minuten als er geen verdere interactie is geweest een record gewoon weer vrijgeven. Zijn ze lang bezig op een pagina? Via je xmlhttprequest elke minuut een teken van leven laten geven, zodat de timeout weer gereset wordt en het record gelockt blijft.

Dus ipv indien je de pagina verlaat het record unlocken, het record gelockt laten zolang die pagina actief is...

Rowdy.nl - X++ by day. C# by night. I drink coffee in the morning and beer in the evening.


Verwijderd

Topicstarter
Verwijderd schreef op donderdag 19 juli 2007 @ 11:21:
Dit hele ontwerp klopt gewoon niet. Het "locken" van records mag best worden aangevraagd door een client. Maar het unlocken ervan zal toch echt ook vanaf de server geregeld moeten worden.
Balen, wou ik ook eens kek doen met ajax :+
Je zou het ongekeerde kunnen doen. Stel je update elke x minuten het tijdstip dat een record gelockt is. Als iemand dan een record opvraagt, mag deze niet minder dan y minuten gelockt zijn.

Op deze manier is een bestand nooit meer dan y minuten gelockt als hij niet meer wordt bekeken/bewerkt door de originele eigenaar van de lock. En als de locker het record heeft aangepast of gesloten kun je de lock meteen verwijderen, net als anders.
Oké, dit moet kunnen.

Dus als 't script een nieuwe record opvraagt zou -ie eerst een check moeten doen op de lock-tijd van de records met status 1. Alle 1-statussen met een lock-tijd die langer dan y minuten geleden zijn kan hij dan weer op 0 zetten.

Ik zou dan de y kunnen bepalen aan de hand van de maximale sessie-tijd?
code:
1
ini_get('session.gc_maxlifetime')


Edit:
@Rddr en Rowdy.nl:
Ook interessant. Dank allemaal, ik ga eens kijken hoe ik het ga aanpakken en zal de oplossing hier neerzetten. Meer geniale invallen zijn nog steeds welkom natuurlijk :)

[ Voor 7% gewijzigd door Verwijderd op 19-07-2007 11:38 ]


  • rhodium
  • Registratie: Augustus 2003
  • Laatst online: 15-11 22:20
Rowdy.nl schreef op donderdag 19 juli 2007 @ 11:30:
Zoals hierboven... In dit geval zou iemand die Javascript uit zet, of gewoon zijn pc afsluit zonder de browsers eerst af te sluiten, de browser van crasht, de stekker uit zijn pc schopt....... een record voor altijd locken...

Een sessie binnen PHP kent altijd een time out, dus na een x aantal minuten als er geen verdere interactie is geweest een record gewoon weer vrijgeven. Zijn ze lang bezig op een pagina? Via je xmlhttprequest elke minuut een teken van leven laten geven, zodat de timeout weer gereset wordt en het record gelockt blijft.

Dus ipv indien je de pagina verlaat het record unlocken, het record gelockt laten zolang die pagina actief is...
Als iemand geen javascript heeft dan locked die niks omdat de timestamp niet aangepast wordt en als iemand de browser afsluit word de timestamp niet geupdate dus unlocked die zich weer. Dus gewoon je data uit de mysql database halen die status hebben van 0 en de timestamp ouder is dan x aantal sec/min.

Verwijderd

Topicstarter
Ik weet wie hier gebruik van gaan maken en ik weet zeker dat javascript niet uit staat. Dat is zo heerlijk aan het maken van dit soort tools: je kent de client :P

  • Rowdy.nl
  • Registratie: Juni 2003
  • Laatst online: 28-11 14:33

Rowdy.nl

Koekje d'r bij?

Rddr schreef op donderdag 19 juli 2007 @ 11:46:
[...]


Als iemand geen javascript heeft dan locked die niks omdat de timestamp niet aangepast wordt en als iemand de browser afsluit word de timestamp niet geupdate dus unlocked die zich weer. Dus gewoon je data uit de mysql database halen die status hebben van 0 en de timestamp ouder is dan x aantal sec/min.
Erm, zal 't ietsje duidelijker proberen te verwoorden.... ;)

Ik zeg nl exact hetzelfde van die timeout. Maar het kan natuurlijk wel zijn dat ze een record soms langer nodig hebben dan de standaard timeout. De TS geeft namelijk geen info waar het exact voor gebruikt gaat worden. als het bijvoorbeeld support requests zijn, moet er misschien iemand gebeld worden, of ergens heen gemaild worden, en dan kan het voorkomen dat zo'n record weer vrijgegeven wordt. Met als gevolg dat er dadelijk twee mensen met hetzelfde record bezig zijn.

Door een stukje javascript op die pagina om de minuut een teken van leven te laten geven, dat dat venster dus gebruikt wordt verloopt die timeout dus niet en wordt het record niet vrijgegeven.

Bijkomend voordeel; je kunt je timeout strakker zetten, zodat mocht je browser crashen, je niet een x aantal minuten hoeft te wachten voordat je weer verder kunt aan je record.

Geen javascript aan? Dan verloopt je record gewoon... :) (het staat dus wel aan, dus zelfs daar hoef je je geen zorgen om te maken)

Rowdy.nl - X++ by day. C# by night. I drink coffee in the morning and beer in the evening.


  • rhodium
  • Registratie: Augustus 2003
  • Laatst online: 15-11 22:20
Rowdy.nl schreef op donderdag 19 juli 2007 @ 12:40:
[...]

Erm, zal 't ietsje duidelijker proberen te verwoorden.... ;)

Ik zeg nl exact hetzelfde van die timeout. Maar het kan natuurlijk wel zijn dat ze een record soms langer nodig hebben dan de standaard timeout. De TS geeft namelijk geen info waar het exact voor gebruikt gaat worden. als het bijvoorbeeld support requests zijn, moet er misschien iemand gebeld worden, of ergens heen gemaild worden, en dan kan het voorkomen dat zo'n record weer vrijgegeven wordt. Met als gevolg dat er dadelijk twee mensen met hetzelfde record bezig zijn.

Door een stukje javascript op die pagina om de minuut een teken van leven te laten geven, dat dat venster dus gebruikt wordt verloopt die timeout dus niet en wordt het record niet vrijgegeven.

Bijkomend voordeel; je kunt je timeout strakker zetten, zodat mocht je browser crashen, je niet een x aantal minuten hoeft te wachten voordat je weer verder kunt aan je record.

Geen javascript aan? Dan verloopt je record gewoon... :) (het staat dus wel aan, dus zelfs daar hoef je je geen zorgen om te maken)
Ik zelf gebruik altijd een timeout van 30seconden. Op het systeem werken 150 mensen en ik heb nooit klachten gehad op traagheid of items die te lang gelockt waren.

  • funkwurm
  • Registratie: December 2005
  • Laatst online: 22-02-2021
Ja ik vind het steeds pollen naar de server dan juist weer erg lelijk. Het klinkt alsof je pagina niet enkel uit het venster dat afsluit bestaat, maar dat er pop-ups komen die afgesloten worden en er dus een moeder-window is. Als je bij de onunload een functie aanroep doen naar een functie die in de parent van dat window staat, doet die de XHR dan wel goed? Of blijft de thread wel van de pop-up waar hij aangeroepen is en gaat hij dus toch verloren bij het sluiten? Zou je in dat geval niet een setTimeout kunnen zetten waardoor de thread van de time-out wel in het moederscherm valt?

Anders zou je (maar dat is wel weer wat lelijk) bij de onunload een nieuwe pop-up kunnen aanroepen die dit doet.

En misschien (bedenk ik me nu) dat het juist werkt als je er een synchroon request van maakt. Immers betekent asynchroon dat de browser niet wacht met verdere executie totdat er antwoord is, synchroon doet dat juist wel, dus misschien wacht het dan ook met afsluiten totdat er antwoord is, maar dat weet ik niet zeker.

Nog een inval: zou je ook niet bij de onunload een return false kunnen geven, dan de XHR doen en bij antwoord het venster zelf sluiten met window.close()?

Iets zegt me dat alleen IE dat pikt, andere browsers zijn te gebruiksvriendelijk om javascript toe te staan het sluiten van en pop-up tegen te gaan.

Ik hoop dat de allereerste optie werkt, die is het meest schoon en orthodox.

Verwijderd

Normaal gesproken werk je hiervoor gewoon met een timeout, na zoveel tijd wordt de boel serverside weer geunlocked. Hoeveel tijd dit is kan je bepalen adhv hoe lang de klus normaal maximaal hoort te duren.

Probleem is namelijk dat je allemaal funky software trucjes kan doen, als je de stekker uit de PC trekt heeft de software niets meer te zeggen ;)

  • funkwurm
  • Registratie: December 2005
  • Laatst online: 22-02-2021
Er is geen "normale" manier om dat te doen. Het ligt aan de toepassing. Wij hebben een applicatie waarbij het nou eenmaal van dusdanig cruciaal belang is dat we liever hebben dat een record dan maar gelocked blijft bij een plotse storing dan dat ze na een bepaalde tijd time outen.

Als ze dan echt unlocked moeten worden dan doen we dat zelf, daar heeft applicatie een unlock-functie voor. Dat is een keuze die TS ook zal moeten maken, maar geen van beiden is per definitie beter of gewoner.

Verwijderd

Das waar, je kunt ook de gebruiker de mogelijkheid geven de boel te unlocken, maar dan moet ie dat ook kunnen doen nadat bijvoorbeeld z'n PC in de soep draait. (En dit niet vergeten).

Ik denk dat de automatische unlock manier (wat bijvoorbeeld ook pas na 8 uur kan zijn als het voorkomt dat de boel 4 uur duurt bijvoorbeeld, daar kan best een marge in zitten) toch net iets vaker voorkomt.

Hoe de vork precies in de steel zit is natuurlijk uniek per applicatie en hangt af van de wensen en eisen.

Verwijderd

Topicstarter
Verwijderd schreef op donderdag 19 juli 2007 @ 11:32:
[...]
Dank allemaal, ik ga eens kijken hoe ik het ga aanpakken en zal de oplossing hier neerzetten.
[...]
Ik heb de tip van Cheatah gebruikt. Mijn MySQL-functie selecteert niet alleen meer records met status Onbehandeld, maar ook met status In behandeling met een laatste datumtijd van wijziging, die te ver in het verleden ligt.
Pagina: 1