JavaScript chat

Sokszor merül fel az igény az emberben, hogy chatet vagy ahhoz hasonló funkcionalitást biztosító weboldalt írjon. Akik webfejlesztésben kicsit járatosak, valószínűleg ismerik az ilyen dolgokat, tehát nekik valószínűleg nem lesz érdekes, ők lapozzanak.

Lehetséges technológiák

  • Flash kliens + FMS szerver: Az FMS (Flash Media Server) lehetőséget biztosít Flashben írt kliensek egymás közötti kapcsolat teremtésére. Nem csak szöveg, hanem audio vagy akár videó formájában is. A probléma vele, hogy egyrészt fizetős (nem kicsit, nagyon) másrészt alternatív platformokon (Linux+ATI) látványos performancia problémákhoz vezethet. Előnye, hogy egyszer megnyit egy kapcsolatot és utána kicsi az overheadje egy üzenet küldésének.
  • Flash + sockets: Ugyanolyan, mint a fenti technológa, azonban nem FMS-hez kapcsolódik, hanem egy tetszőleges TCP porthoz (pl IRC, Jabber szerver). Hátrányként hozzájön az, hogy az ActionScript nagyon kevés natív eszközt biztosít az ilyen műveletekhez (markáns példaként még egy base64-kódolót és libraryként kell betölteni), plusz a mindenféle tűzfalak a nyitott socketeket megfoghatják.
  • Java applet: (Köszönöm, persicsb). Hasonlóan a Flashhez, a böngészőben futó alkalmazásról van szó. A futtatásához JVM (Java Virtual Machine) szükséges. Programozási eszközök, beépített osztályok egész hadseregével rendelkezik, azonban a mai gépek számottevő százalékán nincs telepítve. Kapcsolat szempontjából ugyanazok a hátrányok, mint a Flash + sockets megoldásnál.
  • JavaScript (AJAX): Előnye, hogy ugyanazokkal az eszközökkel dolgozik, mint a böngésző, ezért a tűzfalak nem fogják meg és a videókártyákkal sem lesz nagy gond (hacsak nem csinálunk nagy hülyeséget). Hátránya, hogy a HTTP request alapú, azaz egy üzenet elküldésének nagy az overheadje. Pontosan ezért jól kell megírni, hogy ne legyen belőle probléma.
  • JavaScript (COMET): (TNX Yorirou) Ez a megoldás egyetlen a szerver oldalon addig "fogja" a kapcsolatot, amíg szükséges, információt átpumpálva rajta. Előnye, hogy így nem kell pollozni a szervert (nincs overhead), hátránya, hogy a szerver oldalon fogja az őt kiszolgáló webszervert. (Itt érdemes lehet LigHTTPD-t használni Apache helyett, de erről majd valaki ebben tapasztaltabb fog blogbejegyzést írni, nem én.)
  • ActiveX: Ha valaki a Windows/IE only közösségre gyúr, akkor akár egy tetszőleges programnyelvben írhat ActiveX alkalmazást is. Ebbe nem mennék bele, ez valószínűleg nem játszik komoly versenyzőknél.

Mivel a tudásomhoz a JS (AJAX) áll közel, ezért azt elemzem ki:

  • Inkrementális frissítés: Nem szükséges mindig az egész chat tartalmát elküldeni, elég a változásokat. Ellenkező esetben a szöveg frissítése nagyon gyorsan nagyon lassú lesz. Lehetőleg oldjuk meg, hogy a legutolsó megkapott üzenet timestampje utáni üzeneteket kérdezze le, ellenkező esetben (pl böngészőidő alapján) elveszhetnek üzenetek.
  • Rossz időzítés: Nincs annál nagyobb hiba, mint időzítetten lekérdezni az új üzeneteket és közben, vele párhuzamosan küldeni be az új tartalmat. A requestek összeakadhatnak, üzenetek kétszer jönnek meg, stb. Főleg, ha az első pont szerint készült a chat. Különösen markáns a probléma, ha sok ablak van nyitva.
  • Event queue: A feladatokat szinkronizáljuk össze egy requestbe. Ha szükség van interakcióra, JSON-ba szerializáljuk be az összes küldendő adatot, küldjük el, majd a válaszban kapjuk meg a szükséges válaszokat. Ez kevésbé lényeges egy chat ablaknál, sokkal inkább fontos 5-6 nyitva tartott ablaknál, ahol rengeteg lekérdezés lesz (és belefutunk a böngésző max requests per server limitjébe).
  • JS timer: Nagyon rossz taktika a setTimeout felelőtlen használata. Ha egy request egy időperiódus alatt nem ér véget, akkor összetorlódhatnak a lekérdezések és a már említett problémát okozhatják. Tehát, amikor elkezdjük a feldolgozást, timer kikapcs, majd amikor végeztünk, újra bekapcs.

Nem marad más hátra, csak hogy jó chat írást kívánjak.

Hozzászólások

A jeleneleg elegge kozismert es hasznalt technologia, a Java applet kimaradt.

noigen. 10% is sok, ezért érdemes az oldalra rakni egy JavaMikulás™-t, elvégre csak amiatt bárki hajlandó javát telepíteni :)

utóbbi egy hónap top5:


Internet Explorer	50.78% 	
Firefox			43.35% 	
Chrome			2.53% 	
Opera			2.26%
Safari			0.60%
—-—-—
int getRandomNumber() {
	return 4;//szabályos kockadobással választva.
}		//garantáltan véletlenszerű. xkcd

tény. Ettől függetlenül viszont amennyire emlékszem, még az a legnépszerűbb webes chat platform. Bár sokminden változott azóta, hogy rászoktam az ircre, de egy-két évente felmegyek ilyen chatekre sírva nevetni, és mintha még mindig a Java dívna.
Céges környezetben meg az emberek csak ne webchatelgessenek ;)

—-—-—
int getRandomNumber() {
	return 4;//szabályos kockadobással választva.
}		//garantáltan véletlenszerű. xkcd

"Hasonlóan a Flashhez, a böngészőben futó alkalmazásról van szó. A futtatásához JVM (Java Virtual Machine) szükséges. Programozási eszközök, beépített osztályok egész hadseregével rendelkezik, azonban a mai gépek számottevő százalékán nincs telepítve."
Ehh? ez igy nem kerek. A 30-40% az nem a gepek _szamottevo_ resze, maximum egy resze. A gepek szamottevo reszen telepitve van.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Comet-tel csináltam egy próbálkozást: ichat.hu még működik. Tapasztalat: el kell találni a sorrendet ha session-nel akarod használni. Nekem nem sikerült, maradt a cookie.

lehetséges technológiák += kaazing
lehetséges technológiák += silverlight (duplex polling, etc)

Van egy Java apllet ami megvalósít egy socketet, így állandó kapcsolatban tud maradni a szerverrel. Java applet meg kommunikál a Javascripttel. Javascriptel meg már lehet értelmezni mondjuk az IRC protokolt, vagy más egyebeket. A GUI meg ugye HTML, CSS Javascript trió. Szóval semmilyen HTTP kapcsolatot ne kezdeményez, hanem egy Java applettel kommunikál ami kezdeményezi a kapcsolatot.

sly @ w3m.hu

Ha már egyszer az applet miatt úgyis elindul a JVM, akkor minek az IRC protokollt a marhalassú JS értelemzőn keresztül futtatni? Miért nem egyből direktbe a JVM-en? Hasonlóan a GUI-t is meg lehet pont emiatt csinálni Swinggel. Ha már egyszer úgyis el kell indítani a JVM-et, akkor már mindegy.

1. Az IRC protokoll olyan primitív, hogy anno poénból telneten keresztül is IRCeltem. Amit én tudok értelmezni komolyabb latency nélkül, az egy JS-nek ne legyen már probléma. Nem kell hozzá AI se :)
2. A Swing gui nem illeszkedik rendesen szinte semmibe. Nemigen használom, de nem hiszem, hogy annyi pluszt nyújtana. Nem extjs-re gondolok, ami nyújthat annyit, mint a Swing, de ótvarmód lassú cserébe, egy irc-hez nem kell valami húúde interfész.

—-—-—
int getRandomNumber() {
	return 4;//szabályos kockadobással választva.
}		//garantáltan véletlenszerű. xkcd

Unaloműzés képen?

Ha jobban elolvastad volna az oldalam akkor rájöhettél volna hogy a JS-nek van egy szabványos API-ja ami mögé lehet rakni mondjuk Flash-t (ami meg is történt, hiszen eredetileg Flash volt mögötte). Ha lesz egyszer natív JS socket akkor azt is könnyen mögé lehet integrálni.

sly @ w3m.hu

JavaScript (COMET) : Egyesek az AJAX Push elnevezest hasznaljak.

Amit nem lehet megirni assemblyben, azt nem lehet megirni.

Szerveroldalon nem "fogja" a szervert a comet, a sleep nem használ processzoridőt. Cserébe elfogyhatnak a szálak ha túl sokan lógnak rajta, de ez beállítás kérdése.

Hát egyrészt, hogy nem forkolsz minden kapcsolatra, mert abba belehalsz. A PHP is jó lenne, ha lenne valamilyen application szerver vagy prezisztenciát biztosító réteg (pl adatbázis kapcsolathoz). Ha kifejezetten chat szervert akarsz írni JS backendnek, akkor talán nem is DB, hanem inkább shared memory lehet a megoldás, feladat szerint.

1 gigából el tudsz hajtani kb. 200 klienst... Nekem párhuzamosan max 10 kliensem van, mert support chat lévén, nem annyira nagy a forgalom. Bár igazából a terhelés sem így, sem úgy nem nagy... viszont ha COMETre írna valaki egy célszervert, akkor azt hiszem, verhetetlen lenne.

Most nézem, olyan 50 ms egy sima pollingos frissítés futásideje ugyanazon a kódon amin a pollingot teszteltem. Elvileg csak a szkript futásáig foglal memóriát, viszont egy pici hálózati forgalmat generál akkor is ha nincs semmi változás. Ideális esetben húsz kliens foglal annyi memóriát mint amennyit a long polling esetében egy (hasonlóan ideális esetben).