Avatar billede n-emy Nybegynder
15. august 2005 - 20:21 Der 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.

Hvordan laver jeg det?
Avatar billede jakobdo Ekspert
15. august 2005 - 20:28 #1
Opdateringer af skærmen undgår du ikke.
Hvordan skal nye ting ellers komme til skærmen?
Avatar billede n-emy Nybegynder
15. august 2005 - 20:36 #2
Ja det ved jeg, men hvad siger man så, blinkfri, altså så det ikke "blinker" hver gang den opdaterer?
Avatar billede jakobdo Ekspert
15. august 2005 - 21:19 #3
Kig evt her: http://www.eksperten.dk/spm/320350
OleBole har været på hårdt arbejde.
Avatar billede neess Nybegynder
15. august 2005 - 21:25 #4
Du kan lave det i en iframe der f.eks hele tiden opdatere, så det kun er teksten der bliver loadet. Så vil man ikke rigtigt ligge mærke til det.
Avatar billede neess Nybegynder
15. august 2005 - 21:27 #5
Eller bruge nogle af dem som er lavet færdige :-)
http://phpopenchat.org/
Avatar billede jakobdo Ekspert
15. august 2005 - 21:28 #6
Kig evt også denne tråd: http://www.eksperten.dk/spm/404815
Avatar billede olebole Juniormester
16. august 2005 - 00:51 #7
<ole>

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)

/mvh
</bole>
Avatar billede olebole Juniormester
16. august 2005 - 01:45 #8
Indsætning af elementer kunne ske noget à la dette:

<style type="text/css">
.msgTR {
    color: red;
}
.msgTR .user {
    font-weight: bold;
    vertical-align: top;
}
.msgTR .msg {
    background-color: yellow;
    vertical-align: top;
}
</style>
<script type="text/JavaScript">
var tmplRow = null;
var inx = 0;
function insMsg(aMsgs) {
    var firstRow, oMsg, oRow, aTD, tx, bdy = document.getElementById("msgBody");
  // 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";
    }
    for (var i=0; i<aMsgs.length; i++) {
        oMsg = aMsgs[i];
      // Lav en klon af vores template
        oRow = tmplRow.cloneNode(true);
        aTD = oRow.getElementsByTagName("td");
      // Indsæt tekst i cellerne
        aTD[0].firstChild.nodeValue = oMsg.u;
        aTD[1].firstChild.nodeValue = oMsg.m + " - nummer: " + inx++;
      // Indsæt rækken øverst i tabellen
        bdy.insertBefore(oRow,bdy.firstChild);
    }
  // Slæt rækker i bunden, hvis der er mere end 15
    while (bdy.childNodes.length>5) bdy.removeChild(bdy.lastChild);
}
</script>

<button onclick="insMsg([{'u':'olebole','m':'hello U'}])">Indsæt</button>

<div style="width:300px;height:200px;border:1px solid black;overflow:auto">
<table cellspacing="5">
<tbody id="msgBody">
<tr>
    <td class="user">&nbsp;</td>
    <td class="msg">&nbsp;</td>
</tr>
</tbody>
</table>
</div>
Avatar billede olebole Juniormester
16. august 2005 - 01:47 #9
Variablen 'inx' bruger jeg kun til at skabe lidt forskel på beskederne. In real life kommer de jo fra en iframe - og er forskellige  ;o)
Avatar billede olebole Juniormester
16. august 2005 - 01:53 #10
- og der skulle naturligvis indsnige sig en fejl  :)

  // Slæt rækker i bunden, hvis der er mere end 15
    while (bdy.childNodes.length>15) bdy.removeChild(bdy.lastChild);
Avatar billede olebole Juniormester
16. august 2005 - 02:03 #11
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">&nbsp;</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;
Avatar billede olebole Juniormester
16. august 2005 - 02:10 #12
- og så bør denne linje:
    tmplRow.className = "msgTR";

- vel også ændres til:
    tmplRow.setAttribute("className","msgTR");

- når nu resten er strict DOM  :)
Avatar billede roenving Novice
16. august 2005 - 02:13 #13
-- 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 !-)
Avatar billede olebole Juniormester
17. august 2005 - 17:19 #14
yups ... derfor gør jeg det - omend indirekte  ;o)

var tmplRow = null;

.... bla bla ....

  // 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";
    }
Avatar billede olebole Juniormester
17. august 2005 - 17:20 #15
- man ved jo, hvad der står fra start  :)
Avatar billede roenving Novice
17. august 2005 - 17:25 #16
Hrm, jeg skal vist til at lære at læse indenad !-)
Avatar billede n-emy Nybegynder
08. november 2005 - 23:02 #17
Tak:)

Svar?
Avatar billede olebole Juniormester
09. november 2005 - 08:57 #18
- selvtak  :)
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester