15. august 2005 - 20:21Der er
17 kommentarer og 1 løsning
En chat?
Hey,
Jeg skal igang med en chat, så ville høre hvad den grundlæggende består af, har lavet et forum men en chat skal jo helst være hurtigere, klikfri og fri for opdateringer af skærmen hele tiden.
Njaahhh ... mit eksempel ligger ikke online for tiden - men jeg kan da summe lidt vigtige ting op :)
Først skal du være opmærksom på, at scriptsprog via HTTP-protokollen som udgangspunkt ikke egner sig til chat-applikationer. Derfor gælder det virkelig om at holde tungen lige i munden og gøre alt så effektivt, som overhovedet muligt. Chats er de værste slughalse, en server kan blive præsenteret for. Det eneste sted, du kan tillade dig at være sloppy med perfomance, er på klienten - uden at det på nogen måde skal være en opfordring ;o)
Du starter med at lave en skjult iframe: <iframe src="chat_req.php" name="loadFR" style="display:none"></iframe>
I 'chat_req.php' kan du skrive: ----------------------------------- <? // Her henter du fra DB - og indsætter, hvis der er en besked at sætte ind // Sæt også et timestamp i en cookie // Lad PHP udskrive beskeder i en streng, der f.eks. ender med at se sådan ud: $sJS = "[{'u':'olebole','m':'Davs med dig'}, {'u':'n-emy','m':'det kan du selv være'}]"; ?> <html> <script type="text/JavaScript"> parent.insMsg(<?=$sJS?>); setTimeout("location.reload(true)", 10000); </script> </html> -----------------------------------
I dokumentet med iframe'en har du så en funktion, der formaterer og indsætter HTML i f.eks. en tabel på siden. Begyndelsen på funktionen ser sådan ud:
function insMsg(aMsgs) { var oMsg; for (var i=0; i<aMsgs.length; i++) { oMsg = aMsgs[i]; // Indsæt HTML-element(er) hvor data hentes med: // oMsg.u - brugernavn // oMsg.m - besked } }
Samtidig har du en form med et tekstfelt og en submitknap. Dens target sættes til iframe'ens navn, så siden ikke reloader - men formen i stedet submittes mod iframe'en.
Når brugeren henter beskeder på serveren, checker du hans cookie. Har han ikke fået sat en kage, henter du f.eks. de seneste 15 beskeder til ham. Har han fået sat en cookie med et timestamp i, henter du alle beskeder siden det tidspunkt (sidst, han hentede).
Undlad at bruge * i dine MySQL-sætninger. Hent kun de felter, du virkelig har brug for - og sørg for, din tabel er korrekt indekseret i forhold til de søgninger, du foretager.
Overholder du disse grundregler, har du en god chance for at skrive en fornuftig chat. Udvikler du videre på dette simple eksempel (smilies, visning af køn, etc), skal du hele tiden bruge samme grundtanke:
1. Så meget, som muligt, skal udføres på klienten 2. Så få bytes, som muligt, skal udveksles over WWW - og så sjældent, som muligt 3. Al arbejde på serveren skal udføres så enkelt, kort og optimalt, som muligt
I filen 'chat_req.php' skrev jeg JS-koden på flere linjer for overskuelighedens skyld. I virkeligheden ville jeg rykke det hele op på én linje - og sørge for selve argument-strengen ikke indeholdt unødig white-space. Det er naturligvis også helt bevidst, jeg bruger enkelt-bogstavs navne til objekternes properties ('u' og 'm'). Jo mere, du flueknebber din kode for overflødigt fedt, jo mere realistisk bliver din applikation ;o)
Til de, der måske er begyndt at rode med DOM og stirrer med store øjne, skal jeg lige påpege det lille cowboy-trick, der ligger i at bruge cloneNode til at lave en template. På den måde undgår jeg at skulle lave hvert enkelt element (<tr> og to stk. <td>) for hver række, hvergang der indsættes ;o) En sidegevindst er, at tabellen faktisk skal have indhold fra fødslen for at være valid. Det har den - vi bruger den til noget fornuftigt ... og smider den ad H...... til :)
Endnu et lille cowboy-trick ligger der i at vi jo har en textNode liggende i hver celle: <td class="user"> </td> - hvorfor vi ikke behøver at bruge document.createTextNode - og klistre noden ind i cellen. Vi nøjes blot med at sætte ny nodeValue på den allerede eksisterende textNode: aTD[0].firstChild.nodeValue = oMsg.u;
-- og så bør man vel også teste om den første række er det oprindelige template, eller om det er en af de tidligere chatbeskeder, før man sletter den !-)
// Lav en template af første række og slet rækken, første gang funktionen bliver kørt if (!tmplRow) { firstRow = bdy.getElementsByTagName("tr")[0]; tmplRow = firstRow.cloneNode(true); bdy.removeChild(firstRow); tmplRow.className = "msgTR"; }
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.