Real Time Chat med NodeJS, Socket.io och ExpressJS

NodeJS ger mig möjlighet att skriva back-end kod på ett av mina favorit språk: JavaScript. Det är den perfekta tekniken för att bygga applikationer i realtid. I den här handledningen visar jag dig hur man bygger ett webbchattprogram med hjälp av ExpressJS och Socket.io.

Förresten, om du vill hitta en färdig chattlösning med Node.js, ta en titt på Yahoo! Messenger nod. JS BOT på Envato Market.

Yahoo! Messenger nod. JS BOT på Envato Market

Inställningsmiljö

Naturligtvis är det första att göra NodeJS installerat på ditt system. Om du är Windows eller Mac-användare kan du besöka nodejs.org och ladda ner installationsprogrammet. Om du istället föredrar Linux, föreslår jag att du hänvisar till den här länken. Även om jag inte kommer att gå in på ytterligare detaljer om detta, om du stöter på installationsproblem, är jag glad att hjälpa till; Lämna bara en kommentar under det här inlägget.

När du har installerat NodeJS, är du redo att installera de instrument som behövs.

  1. ExpressJS - det här hanterar servern och svaret på användaren
  2. Jade - mallmotor
  3. Socket.io - möjliggör kommunikation i realtid mellan front-end och back-end

Fortsätt på, i en tom katalog, skapa en package.json fil med följande innehåll.

"namn": "RealTimeWebChat", "version": "0.0.0", "beskrivning": "Realtids webbkall", "beroenden": "socket.io": "latest", "express" senaste "," jade ":" senaste "," författare ":" utvecklare "

Genom att använda konsolen (under Windows-kommandotolken) navigerar du till din mapp och kör:

npm installera

Inom några sekunder har du alla nödvändiga beroenden som hämtats till node_modules katalog.


Utveckla baksidan

Låt oss börja med en enkel server, som kommer att leverera programmets HTML-sida, och fortsätt sedan med de mer intressanta bitarna: realtidskommunikationen. Skapa en index.js fil med följande kärn-expressjs-kod:

var express = kräver ("express"); var app = express (); var port = 3700; app.get ("/", funktion (req, res) res.send ("Det fungerar!");); app.listen (port); console.log ("Lyssna på port" + port);

Ovan har vi skapat en applikation och definierat porten. Därefter registrerade vi en rutt, som i detta fall är en enkel GET-förfrågan utan några parametrar. För närvarande skickar rutens hanterare helt enkelt lite text till kunden. Slutligen, naturligtvis, i botten kör vi servern. För att initiera programmet, från konsolen, kör:

nod index.js

Servern körs, så du borde kunna öppna http://127.0.0.1:3700/ och se:

Det fungerar!

Nu, istället för "Det fungerar" vi borde betjäna HTML. I stället för ren HTML kan det vara fördelaktigt att använda en mallmotor. Jade är ett utmärkt val, som har bra integration med ExpressJS. Detta är det jag brukar använda i mina egna projekt. Skapa en katalog som heter tpl, och lägg följande page.jade filen i den:

!!! html head title = "Real-time webchatt" body #content (style = "width: 500px; height: 300px; margin: 0 0 20px 0; border: solid 1px # 999; overflow-y: scroll; .field (style = 'width: 350px;') input.send (typ = 'knapp', värde = "skicka")

Jades syntax är inte så komplex, men för en fullständig guide föreslår jag att du hänvisar till jade-lang.com. För att kunna använda Jade med ExpressJS behöver vi följande inställningar.

app.set ('views', __dirname + '/ tpl'); app.set ("view engine", "jade"); app.engine ('jade', kräver ('jade') .__ express); app.get ("/", funktion (req, res) res.render ("page"););

Denna kod informerar Express om var dina mallfiler är och vilken mallmotor som ska användas. Det anger all funktionen som kommer att behandla mallens kod. När allt är inställt kan vi använda .göra metod för svar objekt, och skicka helt enkelt vår Jade-kod till användaren.

Utgången är inte speciell vid denna tidpunkt; inget mer än a div element (den med id innehåll), som kommer att användas som hållare för chattmeddelandena och två kontroller (inmatningsfält och knapp), som vi ska använda för att skicka meddelandet.

Eftersom vi kommer att använda en extern JavaScript-fil som håller den främsta logiken, måste vi informera ExpressJS var att leta efter sådana resurser. Skapa en tom katalog, offentlig, och lägg till följande rad innan samtalet till .lyssna metod.

app.use (express.static (__ dirname + '/ public'));

Än så länge är allt bra; Vi har en server som lyckas svara på GET-förfrågningar. Nu är det dags att lägga till Socket.io integration. Ändra den här raden:

app.listen (port);

till:

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

Ovan passerade vi ExpressJS-servern till Socket.io. I själva verket kommer vår realtidskommunikation fortfarande att hända i samma port.

Vid framflyttning måste vi skriva koden som kommer att få ett meddelande från klienten och skicka det till alla andra. Varje Socket.io-ansökan börjar med en förbindelse hanterare. Vi borde ha en:

io.sockets.on ('connection', funktion (uttag) socket.emit ('message', message: 'välkommen till chatten'); socket.on ("send", funktion (data) io. sockets.emit ("message", data);););

Objektet, uttag, som skickas till din hanterare, är faktiskt kontakten till kunden. Tänk på det som en koppling mellan din server och användarens webbläsare. Vid en lyckad anslutning skickar vi en Välkommen typ av meddelande och, naturligtvis, binda en annan hanterare som kommer att användas som mottagare. Som ett resultat bör klienten avge ett meddelande med namnet, skicka, som vi kommer att fånga. Därefter vidarebefordrar vi bara de data som användaren skickat till alla andra uttag med io.sockets.emit.

Med koden ovan är vårt back-end redo att ta emot och skicka meddelanden till kunderna. Låt oss lägga till en del front-end-kod.


Utveckla fronten

Skapa chat.js, och placera den inom offentlig katalog över din ansökan. Klistra in följande kod:

window.onload = function () var messages = []; var socket = io.connect ('http: // localhost: 3700'); var-fält = document.getElementById ("fält"); var sendButton = document.getElementById ("send"); var content = document.getElementById ("content"); socket.on ("message", funktion (data) if (data.message) messages.push (data.message); var html = "; för (var i = 0; i';  content.innerHTML = html;  else console.log ("Det finns ett problem:", data); ); sendButton.onclick = function () var text = field.value; socket.emit ("send", message: text); ; 

Vår logik är insvept i en .onload hanteraren bara för att säkerställa att all uppmärkning och extern JavaScript är fullt laddad. I de närmaste raderna skapar vi en array som lagrar alla meddelanden, a uttag objekt och några genvägar till våra DOM-element. Återigen, i likhet med baksidan, binder vi en funktion som kommer att reagera på socketets aktivitet. I vårt fall är detta en händelse som heter meddelande. När en sådan händelse inträffar förväntar vi oss att vi får ett objekt, data, med fastigheten, meddelande. Lägg till det här meddelandet i vår lagring och uppdatera innehåll div. Vi har också inkluderat logiken för att skicka meddelandet. Det är ganska enkelt, bara att skicka ett meddelande med namnet, skicka.

Om du öppnar http: // localhost: 3700, du kommer att stöta på några fel popup. Det beror på att vi behöver uppdatera page.jade att innehålla nödvändiga JavaScript-filer.

head title = "Script för realtids webbklient" (src = '/ chat.js') (src = '/ socket.io/socket.io.js')

Observera att Socket.io hanterar leverans av socket.io.js. Du behöver inte oroa dig för att hämta filen manuellt.

Vi kan igen köra vår server med nod index.js i konsolen och öppen http: // localhost: 3700. Du bör se välkomstmeddelandet. Självklart, om du skickar något, ska det visas i innehållets div. Om du vill vara säker på att det fungerar öppnar du en ny flik (eller, bättre, en ny webbläsare) och laddar programmet. Det fantastiska med Socket.io är att det fungerar även om du stoppar NodeJS-servern. Fronten kommer fortsätta att fungera. När servern har startats upp igen kommer din chatt att bli bra också.

I sitt nuvarande tillstånd är vår chatt inte perfekt och kräver några förbättringar.


förbättringar

Den första förändringen som vi behöver göra är att meddelandena är identiska. För närvarande är det inte klart vilka meddelanden som skickas av vem. Det bästa är att vi inte behöver uppdatera vår NodeJS-kod för att uppnå detta. Det beror på att servern helt enkelt vidarebefordrar data objekt. Så vi måste lägga till en ny egendom där och läsa den senare. Innan du gör korrigeringar till chat.js, låt oss lägga till en ny inmatning fält där användaren kan lägga till sitt namn. Inom page.jade, ändra kontroller div:

.kontroller | Namn: input # name (style = 'width: 350px;') br input # field (style = 'width: 350px;') inmatning # send (typ = 'knapp', värde = "skicka")

Därefter i code.js:

window.onload = function () var messages = []; var socket = io.connect ('http: // localhost: 3700'); var-fält = document.getElementById ("fält"); var sendButton = document.getElementById ("send"); var content = document.getElementById ("content"); var name = document.getElementById ("namn"); socket.on ("message", funktion (data) if (data.message) messages.push (data); var html = "; för (var i = 0; i'; html + = meddelanden [i] .message + '
'; content.innerHTML = html; else console.log ("Det finns ett problem:", data); ); sendButton.onclick = function () if (name.value == "") alert ("Vänligen skriv ditt namn!"); annat var text = field.value; socket.emit ("send", meddelande: text, användarnamn: name.value); ;

För att sammanfatta förändringarna har vi:

  1. Lades till en ny genväg för användarnamnet inmatning fält
  2. Uppdaterade presentationen av meddelandena lite
  3. Tillfogade en ny Användarnamn egenskap till objektet, som skickas till servern

Om antalet meddelanden blir för högt behöver användaren bläddra på div:

content.innerHTML = html; content.scrollTop = content.scrollHeight;

Tänk på att ovanstående lösning sannolikt inte fungerar i IE7 och under, men det är okej: det är dags för IE7 att blekna. Om du vill ha support, kan du dock använda jQuery:

$ ( "# Content") scrollTop ($ ( "# content") [0] .scrollHeight).

Det skulle också vara trevligt om inmatningsfältet raderas efter att du skickat meddelandet:

socket.emit ("send", meddelande: text, användarnamn: name.value); field.value = "";

Det sista tråkiga problemet är att klicka på skicka knappen varje gång. Med en touch av jQuery kan vi lyssna på när användaren trycker på Stiga på nyckel-.

$ (dokument) .ready (funktion () $ ("# field"). keyup (funktion (e) if (e.keyCode == 13) sendMessage (); ;;);

Funktionen, skicka meddelande, kan registreras, så här:

sendButton.onclick = sendMessage = funktion () ...;

Observera att detta inte är en bra metod, eftersom den är registrerad som en global funktion. Men för vårt lilla test här kommer det att bli bra.


Slutsats

NodeJS är en extremt användbar teknik och ger oss mycket kraft och glädje, särskilt när vi beaktar det faktum att vi kan skriva ren JavaScript. Som du kan se, lyckades vi bara skriva ett fullständigt funktionellt chatprogram i realtid. Ganska snyggt!

Vill du lära dig mer om att bygga webbapplikationer med ExpressJS? Vi har täckt dig!