[ajax] chatbox eigenaardigheden

Pagina: 1
Acties:

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Een tijd geleden heb ik 2 boeken gelezenover ajax en javascript. Om te kijken wat ik ermee kan heb ik geprobeerd een soort van chatbox te maken. Deze doet het volgende:

- Als een gebruiker inlogt dan wordt een teller gestart om te kijken voor hoe lang hij actief is. Als een bepaalde waarde wordt overgeschreden wordt de gebruiker op non-actief gezet.
- Als de gebruiker op enter drukt wordt de teller continue op 0 gezet
- Om de 30 seconden pingt de gebruiker de server om te zeggen dat hij nog aanwezig is. Als de gebruiker de chat wegklikt, zal na 90 seconden de gebruiker van de userlist worden gehaald.

Dit werkt allemaal best goed. Echter heb ik een probleempje. Om de 2 seconden wordt fetch aangeroepen. Hierin wordt het user lijstje en de chattext opgehaald en getoond, door fetchText en fetchUsers aan te roepen. Echter als ik in de callback van fetchUsers niet fethText aanroep, dan laat hij in de userlist de chattext zien. Volgens mij heeft dit te maken met de variabele xmlHttp die dan overschreven wordt. Ik vroeg me af of hie rniet een oplosisng voor is, zodat ik in fetchUsers niet fetchText hoef aan te roepen, maar enkel in fetch.

Ik heb de chat even live gezet op http://www.12nieuws.nl/sign-in/

Je hoeft je niet eerst aan te melden, om i de chat te komen, maar je kan alleen een username invoeren om de chat te bekijken.

Daarnaast vroeg ik me af of ik het geheel nog iets beter kan tweaken, om de serverload te verminderen. Wat zijn hier manieren voor?

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
function fetch() {
    window.clearTimeout(timeout);
    fetchText();
    fetchUsers();
    if (timedout != 1) {
        setTimers();
    }
}

function fetchText() {
    url = "textchat.php?r=" + rnd;
    createXMLHttpRequest();
    xmlHttp.open("GET",url);
    xmlHttp.send(null);
    xmlHttp.onreadystatechange = callbackFetchtext;
}

function callbackFetchtext() {
    if (xmlHttp.readyState == 4) {
        if (xmlHttp.status == 200) {
            obj = document.getElementById("chatlist");
            obj.innerHTML = xmlHttp.responseText;
        }
    }
}

function fetchUsers() {
    url = "userchat.php?r=" + rnd;
    createXMLHttpRequest();
    xmlHttp.open("GET",url);
    xmlHttp.send(null);
    xmlHttp.onreadystatechange = callbackFetchusers;
}

function callbackFetchusers() {
    if (xmlHttp.readyState == 4) {
        if (xmlHttp.status == 200) {
            obj = document.getElementById("userlist");
            obj.innerHTML = xmlHttp.responseText;
            fetchText();
        }
    }
}

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12 09:49
Als je een variabel niet met var declareert, dan wordt hij uit een hogere scope gehaalt. Het is dus idd. heel goed mogelijk dat fetchUsers en fetchText met dezelfde variabel werken. Je kunt het beste createXMLHttpRequest een nieuw object laten returnen en die opvangen in een locale variabel. Overigens kun je je event handler beter koppelen voordat je send aanroept.

Noushka's Magnificent Dream | Unity


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Hoe bedoel je dat precies? xmlHttp wordt wel gedeclareerd, dit is een fragment van de gehele chatclient ;-)

[ Voor 61% gewijzigd door RSD op 14-06-2006 13:56 ]


  • om3ega
  • Registratie: Maart 2001
  • Laatst online: 12-12 18:59
Ik kreeg bijna direct een user timed out :) .. (Firefox 1.5.0.4)

Verwijderd

om3ega schreef op woensdag 14 juni 2006 @ 13:58:
Ik kreeg bijna direct een user timed out :) .. (Firefox 1.5.0.4)
Deze kreeg ik ook in IE7, in 2 minuten

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Hij staat aardig snel om te testen, ander szo lang wachten... maar in FF ziet hij er idd erg beroerd uit.

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12 09:49
RSD schreef op woensdag 14 juni 2006 @ 13:55:
Hoe bedoel je dat precies? xmlHttp wordt wel gedeclareerd, dit is een fragment van de gehele chatclient ;-)
Ik zou nooit met globale variabelen werken als dat niet hoeft. Door middel van lokale variabelen en closure kun je dit veel beter oplossen:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fetchText() {
    url = "textchat.php?r=" + rnd;
    var xmlHttp = createXMLHttpRequest();
    xmlHttp.open("GET",url);
    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4) {
            if (xmlHttp.status == 200) {
                obj = document.getElementById("chatlist");
                obj.innerHTML = xmlHttp.responseText;
            }
        }
    };
    xmlHttp.send(null);
}


Hierbij is het dan wel zaak dat je createXMLHttpRequest een nieuw object laat returnen en niet de waarde van een globale variabel. Met var declareer je hem in de functie lokaal, zodat je geen last hebt van andere functies die toevallig gebruik maken van variabelen met dezelfde naam. fetchUsers kun je op dezelfde manier doen.

[ Voor 4% gewijzigd door Michali op 14-06-2006 17:33 ]

Noushka's Magnificent Dream | Unity


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik had de functies al aangepast, zoals je kan zien in de source van het script.

  • crisp
  • Registratie: Februari 2000
  • Nu online

crisp

Devver

Pixelated

Er is op zich niets mis met het hergebruiken van XMLHttpRequest objecten die al klaar zijn met een vorig request, dat is ook veel efficienter. Je zou een pool van XMLHttpRequest objecten kunnen maken en dan de eerstvolgende gebruiken die niet busy is. Er is hier laatst ook nog een topic geweest over het queue-en van requests (aangezien browsers sowieso maar 2 requests naar dezelfde server tegelijkertijd kunnen/zullen/mogen afhandelen) - ik weet niet in hoeverre ik in mijn voorbeeldcode aldaar de objecten hergebruikte (ws niet :P), maar zeker als je met meerdere requests simultaan gaat werken zou ik een dergelijk queue-ing systeem ook zeker implementeren om problemen te voorkomen.

[ Voor 26% gewijzigd door crisp op 14-06-2006 19:49 ]

Intentionally left blank


  • funkwurm
  • Registratie: December 2005
  • Laatst online: 22-02-2021
Is het niet veel wenselijker om alle gegevens in 1 request binnen te halen. En dan middels XML gescheiden zodat je met JS-DOM functies de verschillende deelgegevens kunt splitsen en plaatsen waar alles hoort? (responseXML dus ipv responseText)

  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik weet niet wat beter is en of meer resources vreet. Ik schrijf nu alleen naar 3 verschillende tekst bestanden weg en heb dus geen xml parser nodig in php. Die pages worden om de twee seconden ge-refreshed. Het gaat erom dat de chat supersnel is.

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 09-12 09:49
1 request is altijd(?) sneller dan 2, zeker als je iedere keer 2 requests tegelijk doet is het zeker aan te raden dat in 1 keer te doen. Je hoeft ook niet persé met XML formaat te werken. Ik zou zeggen, ga eens op zoek naar JSON op Google. Of je zou een eigen formaat kunnen bedenken en dat kunnen parsen, als dat nog sneller gaat.

Noushka's Magnificent Dream | Unity


  • RSD
  • Registratie: Maart 2001
  • Laatst online: 08-02-2017
Ik gebruik nu 4 request. 1 voor de userlist, 1 voor de chatlist en 1 om te pingen en 1 voor het posten. Dit is veel te veel dus. Het pingen kan ik natuurlijk ook in een cronjob zetten. En idd ik denk dat ik alles in 1 request moet doen. En misschien toch in 2, maar in ieder geval de userlist en de chatlist in 1. Zelf heb ik 0 ervaring met json en hoe dat te implementeren in Javascript.

Ik vroeg me af hoe ik het posten het beste kan doen, moet dat ook nog in 1 request gebeuren?

[ Voor 18% gewijzigd door RSD op 15-06-2006 13:15 ]


  • Blaise
  • Registratie: Juni 2001
  • Niet online
Ik vermoed dat het verminderen van het aantal requests belangrijker is dan de hoeveelheid data die per request heen en weer wordt gestuurd, als het gaat om overbelasting van je server. Daarom zou je een post kunnen combineren met de rest van de requests, dus als je een post doet dat je dan ook gelijk alle data terugkrijgt van de userlist en chatlist en dat de updatetimer dan weer wordt refreshed.

Wat ik momenteel doe bij een site met xmlhttprequests, is de javascript genereren met PHP en dan in javascript eval(xmlHttp.responseText). Dan heb je volledige vrijheid om in PHP alle javascript te vormen die je maar wil, afhankelijk van wat de client heeft verstuurd naar de server. Ik vind dat handiger dan voor elk dynamisch onderdeel van de chat een javascript functie te maken.
Pagina: 1