Använda Node.js och Websockets för att skapa en chattjänst

Node.js och Websockets är den perfekta kombinationen för att skriva väldigt snabba, lagfria program som kan skicka data till ett stort antal kunder. Så varför börjar vi inte lära oss om dessa två ämnen genom att bygga en chattjänst! Vi kommer att se hur du installerar Node.js-paket, servera en statisk sida till klienten med en grundläggande webbserver och konfigurera Socket.io för att kommunicera med klienten.


Varför välja Node.js och Socket.io?


Så varför använda den här kombinationsrutan?

Det finns många plattformar som kan köra en chattprogram, men genom att välja Node.js behöver vi inte lära oss ett helt annat språk, det är bara JavaScript, men serverns sida.

Node.js är en plattform som bygger på Chromes JavaScript runtime för att göra byggnadsprogram i JavaScript som körs på servern, enkelt. Node.js använder en händelsedriven, icke-blockerande I / O-modell, vilket gör den perfekt för att bygga realtidsprogram.

Allt fler Node.js applikationer skrivs med realtidskommunikation i åtanke. Ett känt exempel är BrowserQuest från Mozilla, en MMORPG skrivet helt i Node.js vars källkod har släppts på Github.

Node.js levereras med en inbyggd paketchef: npm. Vi använder det för att installera paket som hjälper till att påskynda vår applikationsutvecklingsprocess.

Vi använder tre paket för denna handledning: Jade, Express och Socket.io.

Socket.io: Plugin Node.js Websockets

Huvuddelen av vår ansökan är realtidskommunikationen mellan klienten och servern.

HTML5 introducerar Websockets, men det är långt ifrån att stödjas av alla användare, så vi behöver en backup-lösning.

Socket.io är vår backup-lösning: den kommer att testa Websocket-kompatibilitet och om den inte stöds kommer den att använda Adobe Flash, AJAX eller en iFrame.

Slutligen stöder den en mycket stor uppsättning webbläsare:

  • Internet Explorer 5.5+
  • Safari 3+
  • Google Chrome 4+
  • Firefox 3+
  • Opera 10.61+
  • iPhone Safari
  • iPad Safari
  • Android WebKit
  • WebOs WebKit

Det erbjuder också mycket enkla funktioner att kommunicera mellan servern och klienten, på båda sidor.

Låt oss börja med att installera de tre paket som vi behöver.


Installera våra beroende

Npm tillåter oss att installera paket mycket snabbt, med en rad, så först gå till din katalog och ha npm hämta de nödvändiga paketen:

npm installera express jade socket.io

Nu kan vi börja bygga vår server-sidans kontroller för att tjäna huvudsidan.

Vi ska spara hela serverns kod i en "server.js" fil som kommer att utföras av Node.js.


Serverar en enda statisk sida


För att servera vår statiska sida använder vi Express, ett paket som förenklar hela sändningssidan för serverns sida.

Så låt oss inkludera det här paketet i vårt projekt och starta servern:

 var express = kräver ("express"), app = express.createServer ();

Därefter måste vi konfigurera Express för att betjäna sidan från repertoarvyn med den Jade-templerande motorn som vi installerade tidigare.

Express använder som standard en layoutfil, men vi behöver inte det eftersom vi bara tjänar en sida, så istället kommer vi att inaktivera det.

Express kan också servera en statisk repertoar till klienten som en klassisk webbserver, så vi skickar en "offentlig" mapp som innehåller alla våra JavaScript, CSS och bildfiler.

 app.set ('views', __dirname + '/ views'); app.set ("view engine", "jade"); app.set ("visa alternativ", layout: false); app.configure (funktion () app.use (express.static (__ dirname + '/ public')););

Låt oss sedan skapa två mappar i vår projektmapp som heter "offentlig" och "åsikter".

Nu behöver vi bara konfigurera Express för att servera en "Home.jade" fil, som vi kommer att skapa på ett ögonblick, och sedan ställa in Express för att lyssna på en viss port.

Jag kommer att använda port 3000 men du kan använda vad du helst föredrar.

 app.get ('/', funktion (req, res) res.render ('home.jade');); app.listen (3000);

Skapa Jade Template Page


Node.js använder templerande motorer för att servera webbsidor. Det är användbart att skicka dynamiska sidor och bygga dem snabbare.

I den här handledningen använder vi Jade. Syntaxen är mycket tydlig och den stöder allt vi behöver.

"Jade är en högpresterande templerande motor som påverkas starkt av Haml och implementeras med JavaScript för Node."

Nu kommer jag inte att gå över Jade i detalj, om du behöver mer hjälp, kan du hitta mycket välskriven dokumentation på Github repo.

Jade-konfiguration

Vi installerade Jade tidigare, men vi måste inkludera det i vår server.js fil som vi gjorde för Express.

Enligt konventionen inkluderar vi våra bibliotek högst upp i vår fil för att använda dem senare, utan att behöva kontrollera om de redan ingår. Så sätt följande kod högst upp på din "server.js" fil:

 Var jade = kräver ('jade');

Och det avslutar vår Jade-konfiguration. Express är redan inställd för att använda Jade med våra visningsfiler, för att skicka ett HTML-svar, behöver vi bara skapa den filen.

Skapa vår hemsida

Om vi ​​startar vår server nu kraschar det eftersom vi ber vår app att skicka en sida som inte existerar ännu.

Vi kommer inte att skapa en fullfjädrad sida, bara något grundläggande som har en titel, en behållare för meddelandena, ett textområde, en sändningsknapp och en användarräknare.

Fortsätt och skapa en "Home.jade" sida inuti "åsikter" mapp med följande kod:

 doktyp 5 html huvudtitel Skript script (src = 'https: //ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js') (src = "/ socket.io/socket. Io.js ") script (src =" script.js ") body div.container header h1 Ett chattprogram med Node.js och Socket.io input (typ = 'text') # pseudoInput-knapp # pseudoSet Set Pseudo div # chatEntries div # chatControls input (typ = 'text') # messageInput-knapp # Skicka Skicka

"Jade handlar om inryckning"

Jade-språket handlar om inryckning. Som du kan se behöver vi inte stänga våra behållare, bara indenting barnen i förälderbehållaren är tillräckligt.

Vi använder också en period "" och ett pund tecken "#" för att ange elementets klass eller ID, precis som i en CSS-fil.

Vi länkar också i tre skript längst upp i filen. Den första är jQuery från Google CDN, därefter har vi Socket.io-skriptet som serveras automatiskt av paketet, och slutligen en "script.js" fil som kommer att behålla alla våra anpassade JS-funktioner.


Socket.io Server-Side Configuration


Socket.io är händelsebaserad, precis som Node. Det syftar till att göra realtidsapplikationer möjliga i varje webbläsare och mobilenhet, suddiga linjerna mellan dessa olika transportmekanismer. Det är vårdfritt, realtid och 100% JavaScript.

Liksom de andra modulerna måste vi inkludera det i vår server.js fil. Vi kommer också att kedja på vår expressserver för att lyssna på anslutningar från samma adress och port.

 var io = kräver ('socket.io'). lyssna (app);

Den första händelsen vi kommer att använda är anslutningsevenemanget. Den avfyras när en klient försöker ansluta till servern. Socket.io skapar ett nytt uttag som vi ska använda för att ta emot eller skicka meddelanden till kunden.

Låt oss börja med att initiera anslutningen:

 io.sockets.on ("anslutning", funktion (uttag) // våra andra händelser ...);

Den här funktionen tar två argument, den första är händelsen och den andra är återuppringningsfunktionen, med socketobjektet.

Med hjälp av kod så kan vi skapa nya händelser på klienten och på servern med Socket.io. Vi kommer att ställa in "pseudo" händelse och "meddelande" händelse nästa.

För att göra detta är det verkligen enkelt, vi använder bara samma syntax, men den här gången med vår uttag objekt och inte med "io.sockets" (med ett "s" -objekt). Detta gör det möjligt för oss att kommunicera specifikt med en klient.

Så inuti vår anslutningsfunktion, låt oss lägga till i "pseudo" händelsekod.

 socket.on ('setPseudo', funktion (data) socket.set ('pseudo', data););

Återuppringningsfunktionen tar ett argument, det här är data från klienten och i vårt fall innehåller den pseudo. Med "uppsättning" funktion, tilldelar vi en variabel till uttaget. Det första argumentet är namnet på denna variabel och den andra är värdet.

Därefter måste vi lägga till koden för "meddelande" händelse. Det kommer att få användarens pseudo, sända en array till alla klienter som innehåller meddelandet vi mottog samt användarens pseudo och loggar in i vår konsol.

 socket.on ("message", funktion (meddelande) socket.get ("pseudo", funktion (fel, namn) var data = 'message': meddelande, pseudo: namn; socket.broadcast.emit meddelande ", data); console.log (" användare "+ namn +" skicka detta: "+ meddelande);));

Detta kompletterar vår server-sida konfiguration. Om du vill kan du fortsätta och använda andra händelser för att lägga till nya funktioner i chatten.

Det fina med Socket.io är att vi inte behöver oroa oss för att hantera klientuppkopplingar. När det kopplas från, kommer Socket.io inte längre att få svar på "heartbeat" -meddelanden och kommer att avaktivera sessionen som är associerad med klienten. Om det bara var en tillfällig frånkoppling, kommer klienten att återansluta och fortsätta med sessionen.


Socket.io Client-Side Configuration

Nu när vår server är konfigurerad för att hantera meddelanden behöver vi en klient att skicka dem.

Klientsidan av Socket.io är nästan densamma som serverns sida. Det fungerar också med anpassade händelser och vi kommer att skapa samma som på servern.

Så först skapa en "script.js" filen inuti offentlig mapp. Vi lagrar alla våra funktioner inuti den.

Vi behöver först starta socket.io-anslutningen mellan klienten och servern. Den lagras i en variabel, som vi senare kommer att använda för att skicka eller ta emot data. När anslutningen inte passerar några argument kopplas den automatiskt till servern som ska tjäna sidan.

 var socket = io.connect ();

Låt oss sedan skapa några hjälpfunktioner som vi behöver senare. Den första är en enkel funktion för att lägga till ett meddelande på skärmen med användarens pseudo.

 funktion addMessage (msg, pseudo) $ ("# chatEntries"). append ('

'+ pseudo +': '+ msg +'

');

Den här hjälpen använder tilläggsfunktionen från jQuery för att lägga till en div i slutet av #chatEntries div.

Nu ska vi skriva en funktion som vi kan ringa när vi vill skicka ett nytt meddelande.

 funktionen skickadMessage () if ($ ('# messageInput') .val ()! = "") socket.emit ('message', $ ('# messageInput') .val ()); addMessage ($ ('# messageInput') .val (), "Me", nytt datum (). toISOString (), true); $ ('# messageInput') .val (");

Först kontrollerar vi att vår textarea inte är tom, så skickar vi ett paket som heter "meddelande" till servern som innehåller meddelandetexten, skriver vi ut det på skärmen med vår "Lägg till meddelande" funktion och till sist tar vi bort all text från textområdet.

Nu när kunden öppnar sidan måste vi först ange användarens pseudo. Den här funktionen skickar pseudotjänsten till servern och visar textarea och inmatningsknappen.

 funktion setPseudo () if ($ ("# pseudoInput") .val ()! = "") socket.emit ('setPseudo', $ ("# pseudoInput") .val ()); $ ( '# ChatControls') visa (). $ (# PseudoInput) dölja (). $ (# PseudoSet) dölja (). 

Dessutom döljer vi pseudoinställningsreglagen när den skickas till servern.

Nu behöver vi, precis som vi gjorde på serverns sida, se till att vi kan ta emot inkommande meddelanden och den här gången skriver vi ut dem på skärmen. Vi använder samma syntax men den här gången kallar vi "Lägg till meddelande" fungera.

 socket.on ("message", funktion (data) addMessage (data ['message'], data ['pseudo']););

Precis som med vår serverkonfiguration är paketet som skickas till klienten en grupp som innehåller meddelandet och pseudotjänsten. Så vi ringer bara vår "Lägg till meddelande" funktion som passerar i meddelandet och pseudotypen, som vi extraherar från det mottagna datapaketet.

Nu behöver vi bara lägga till initialiseringsfunktionen som avfyras när sidan är fulladdat.

 $ (funktion () $ ("# chatControls"). Hide (); $ ("# pseudoSet"). klicka (funktion () setPseudo (); $ ("# submit"). ) skickat meddelande();); );

Först döljer vi chattkontroller innan pseudotillståndet är inställt och sedan ställer vi in ​​två klicklistor som lyssnar på klick på våra två inlämningsknappar. Den första är för pseudo och den andra är för meddelandena.

Och det bryter upp vårt klientsideskript.


Slutsats

Vi har nu en fungerande chattjänst. För att starta det, kör bara följande kommando:

 nod server.js

I din terminal bör du få ett meddelande från Socket.io som säger att servern är igång. För att se din sida gå till 127.0.0.1:3000 (eller vilken port du valde tidigare).


Designen är väldigt grundläggande, men du kan enkelt lägga till i ett stilark med CSS3-övergångar för inkommande meddelanden, HTML5-ljud eller Bootstrap från Twitter.

Som du kan se är servern och klientskripten ganska lika: det här är kraften hos Node.js. Du kan bygga en applikation utan att behöva skriva koden två gånger.

Slutligen kan du ha märkt att det bara tog 25 koder av kod inuti vårt server.js fil för att skapa en funktionell chattapp med fantastisk prestanda. Det är väldigt kort, men det fungerar också väldigt bra.

Nu om du är intresserad, har jag skapat ett bättre chattjänsteansökan med en snygg design tillsammans med några ytterligare funktioner. Det är värd på Nodester och källkoden finns på Github.

Här är en förhandsvisning av den.


Tack för att du läser.