Chat Applicatie met Angular en Socket.IO

Inleiding

We zullen RxJS, Angular, express (Node.js) & Socket.IO gebruiken om een chat applicatie te maken. We zullen te zien krijgen hoe nuttig RxJS kan zijn in dit scenario. Om alles vlot en gemakkelijk te laten verlopen zullen we Angular CLI gebruiken om een basis client structuur te genereren en ons een boilerplate te geven voor de eenvoudigste werkende Angular applicatie. Op de back-end zullen we Node.js gebruiken met express en Socket.IO. De redenering hierachter is dat Socket.IO zeer eenvoudig is op te zetten en mee te werken. Bovendien biedt het zowel server- als client-side bibliotheken. Socket.IO gebruikt WebSocket protocol om real-time bidirectionele communicatie mogelijk te maken.

Als je direct naar het deel wilt gaan waar we RxJS gebruiken om de chatberichten af te handelen, klik dan hier.

Laten we beginnen!

Socket.IO server setup

Als u Angular CLI niet hebt geïnstalleerd, kunt u deze vrij eenvoudig installeren:

npm i -g @angular/cli

Mappenstructuur opzetten

Om alles netjes te houden, gaan we een nieuwe rxjs-chat map aanmaken voor ons kleine project. Het moet dienen als hoofdmap voor Angular en Socket.IO apps.

Laten we een basis Angular app maken met Angular CLI. Start in onze projectmap uw favoriete terminal en voer het volgende commando uit:

ng new rxjs-chat

Geef het een beetje tijd. Nadat het klaar is met het maken van de basis structuur en het installeren van npm packages zullen we de nieuw aangemaakte Angular project map hernoemen naar client. Daarna maken we in dezelfde hoofdmap de map server aan voor onze Socket.IO server. Nu hebben we twee mappen in onze rxjs-chat map:

  • client – Angular client app
  • server – binnenkort Node’s Socket.IO server
Installeren van lokale pakketten

In de server map zullen we package.json bestand genereren door het volgende commando uit te voeren:

npm init -y

Daarna installeren we onze afhankelijkheden en slaan ze op in package.json:

npm install express socket.io --save

In dezelfde map maken we index.js bestand voor onze server app. De inhoud van het bestand moet als volgt zijn:

We maken een instantie van express en slaan deze op in app variabele. Daarna maken we server met http module. Dan geven we express door aan http.Server() methode. Express zal dienen als de handler voor verzoeken aan onze server. In ruil daarvoor krijgen we de instantie van de server die we opslaan in server variabele.

In de volgende twee regels code binden we de socket.IO met onze http server:

let socketIO = require('socket.io');

let io = socketIO(server);

Daarna luisteren we naar connectie-events van socket.IO en loggen we zodra een gebruiker een verbinding met de server tot stand heeft gebracht. Tot slot starten we de server en luisteren we op de opgegeven poort, in ons geval is dat poort 3000.
Laten we onze server nu echt starten door het volgende uit te voeren in de servermap:
node index.js
Daarna zou u de volgende melding moeten krijgen: “gestart op poort: 3000”.

Connecting to Socket.IO

We hebben een server die draait op poort 3000. Nu is het tijd om te zien hoe we verbinding kunnen maken met de server vanuit onze Angular app. Hiervoor moeten we de Socket.IO client bibliotheek installeren. We voeren het volgende commando uit in onze client map:

npm install socket.io-client --save

Nu we toch bezig zijn, laten we de Angular app starten via Angular CLI:

ng serve -o

Nu hebben we onze app gestart. We kunnen zien dat onze standaard browser zojuist een nieuw tabblad heeft geopend dat wijst naar localhost. Daarom hebben we het argument -o gebruikt om de browser te openen.

Service maken voor communicatie met de server

Ik ga het chat.service.ts app.chat.service.ts noemen en het in de map src plaatsen. De service zal nu zo eenvoudig mogelijk zijn:

De service toevoegen aan de module providers

Ook, laten we onze ChatService toevoegen aan de lijst van providers in de AppModule in het bestand app.module.ts:

De service in onze component injecteren

Ten slotte gaan we de service importeren en gebruiken in onze app.component.ts bestand:

import { ChatService } from './app.chat.service';

En we gaan de ChatService in onze constructor injecteren:

constructor(chatService: ChatService) { }

Als resultaat hebben we het volgende bestand:

Als alles volgens verwachting is verlopen na het opslaan van de wijzigingen, zou u het bericht ‘gebruiker verbonden’ moeten zien in de terminal waar u de node-app hebt gestart:

$ node index.js
started on port: 3000
user connected

Hiermee kunnen we zeggen dat we er eindelijk in geslaagd zijn om verbinding te maken met onze Socket IO-server. Nu is het tijd om daadwerkelijk data te versturen via Socket IO events.

Een bericht sturen naar Socket.IO

Tijd om onze tot nu toe eenvoudige ChatService te verbeteren met een optie om een bericht naar de server te sturen:

Om dit te laten werken moeten we sendMessage() van ons AppComponent gebruiken:

Eindelijk, laten we de gebruiker een eenvoudige tekstinvoer en een knop geven zodat hij een bericht kan sturen:

Om dit alles te laten werken moeten we op de server luisteren naar ‘new-message’-gebeurtenissen die we van ChatService hebben uitgezonden:

socket.on('new-message', (message) => {
console.log(message);
});

Nu ziet onze index.js ziet er als volgt uit:

Als je met de code wilt spelen, kun je die vinden op mijn GitHub repo – rxjs-chat.

Communiceren met andere gebruikers

Om ons bericht naar andere gebruikers te sturen, hoeven we alleen maar de console.log(message) binnenkant van onze ‘new-message’ event callback te veranderen in io.emit(message):

En wat doet io.emit()? Simpel gezegd stuurt het een event naar iedereen die met de server verbonden is.

Laten we met onze server communiceren via ChatService. We zullen een nieuwe methode aan onze service toevoegen voor dit doel – getMessages. Het zal een Observable teruggeven die we zullen maken met Observable.create() methode. Elke keer als de socket een nieuw bericht ontvangt, gebruiken we observer.next() om het door te sturen naar observers.

Daarna abonneren we ons op deze Observable vanuit ons AppComponent:

We hebben een nieuwe messages array gemaakt waarin we de berichten opslaan die we van de server ontvangen. We zullen die berichten moeten tonen in onze template. Dat is de perfecte use case voor ngFor: