Csevegő alkalmazás Angular és Socket.IO segítségével

Bevezetés

Az RxJS, Angular, express (Node.js) & Socket.IO segítségével készítünk egy chat alkalmazást. Meglátjuk, hogy az RxJS mennyire hasznos lehet ebben a forgatókönyvben. A dolgok zökkenőmentessé és egyszerűvé tétele érdekében Angular CLI-t fogunk használni az alapvető kliensstruktúra létrehozásához, és kapunk egy boilerplate-et a legegyszerűbben működő Angular alkalmazáshoz. A back-endben Node.js-t fogunk használni express-szel és Socket.IO-val. Ennek oka az, hogy a Socket.IO-t nagyon könnyű beállítani és dolgozni vele. Ráadásul mind szerver-, mind kliensoldali könyvtárakat biztosít. A Socket.IO elsősorban a WebSocket protokollt használja a valós idejű kétirányú kommunikáció lehetővé tételéhez.

Ha közvetlenül arra a részre akarsz ugrani, ahol RxJS-t használunk a chat üzenetek kezelésére, kattints ide.

Kezdjük el!

Socket.IO szerver beállítása

Ha nincs telepítve az Angular CLI, akkor elég könnyen telepítheted:

npm i -g @angular/cli

Mappastruktúra beállítása

A tisztaság érdekében új rxjs-chat mappát hozunk létre a kis projektünkhöz. Ez szolgáljon gyökérmappaként az Angular és Socket.IO alkalmazások számára.

Elkészítünk egy alap Angular alkalmazást az Angular CLI segítségével. A projekt mappánkban indítsuk el a kedvenc terminálunkat és futtassuk a következő parancsot:

ng new rxjs-chat

Adjunk neki egy kis időt. Miután elkészült az alapstruktúra létrehozása és az npm csomagok telepítése után átnevezzük az újonnan létrehozott Angular projekt mappát kliensre. Ezt követően ugyanebben a gyökérmappában hozzuk létre a server mappát a Socket.IO szerverünk számára. Most már két mappánk van az rxjs-chat mappánkon belül:

  • client – Angular kliens alkalmazás
  • server – hamarosan Node Socket.IO szerver
Lokális csomagok telepítése

A szerver mappában csomagot fogunk generálni.json fájlt a következő parancs futtatásával:

npm init -y

Ezután telepítjük a függőségeinket és elmentjük a package.json fájlba:

npm install express socket.io --save

Ezután ugyanebben a mappában létrehozzuk az index.js fájlt a szerver alkalmazásunkhoz. A fájl tartalmának a következőnek kell lennie:

Elkészítünk egy express példányt és a app változóba tároljuk. Ezután létrehozzuk a szervert a http modullal. Ezután átadjuk a express értéket a http.Server() metódusnak. Az express a szerverünkhöz érkező kérések kezelőjeként fog szolgálni. Cserébe megkapjuk a szerver példányát, amit a server változóban tárolunk.

A következő két kódsorban a socket.IO-t kötjük a http server:

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

let io = socketIO(server);

Azután figyeljük a socket.IO kapcsolati eseményét és naplózzuk, ha egy felhasználó kapcsolatot létesített a szerverrel. Végül elindítjuk a szervert és hallgatjuk a megadott portot, esetünkben ez a 3000-es port.
Ténylegesen indítsuk el a szerverünket a szerver mappában a következők futtatásával:
node index.js
Ezután a következő üzenetet kell kapnunk: “elindult a porton: 3000”.

Connecting to Socket.IO

A 3000-es porton fut a szerverünk. Most itt az ideje, hogy megnézzük, hogyan tudunk csatlakozni a szerverhez az Angular alkalmazásunkból. Ehhez telepítenünk kell a Socket.IO klienskönyvtárat. A következő parancsot futtatjuk a kliens mappánkban:

npm install socket.io-client --save

Ha már itt tartunk futtassuk az Angular alkalmazást az Angular CLI-n keresztül:

ng serve -o

Most már fut az alkalmazásunk. Láthatjuk, hogy az alapértelmezett böngészőnk épp most nyitott egy új lapot, amely a localhost-ra mutat. Ezért használtuk a -o argumentumot a böngésző megnyitásához.

Creating service for communication with server

Megnevezem chat.service.ts app.chat.service.ts-nek és elhelyezem az src mappában. A szolgáltatás egyelőre a lehető legegyszerűbb lesz:

A szolgáltatás hozzáadása a modul szolgáltatóihoz

Ezeken kívül adjuk hozzá a ChatService szolgáltatásunkat az app.module.ts fájlban lévő AppModule-on belüli providers listához:

A szolgáltatás beillesztése a komponensünkbe

Végül importáljuk és használjuk a szolgáltatást az app.component-on belül.ts fájlban:

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

A ChatService-t pedig a konstruktorunkba injektáljuk:

constructor(chatService: ChatService) { }

Az eredmény a következő fájl lesz:

Ha minden a várakozásoknak megfelelően ment, akkor a módosítások mentése után a “user connected” üzenetet kell látnunk abban a terminálban, ahol a node app-ot elindítottuk:

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

Ezért elmondhatjuk, hogy végre sikerült csatlakoznunk a Socket IO szerverünkhöz. Most itt az ideje, hogy ténylegesen küldjünk néhány adatot a Socket IO eseményeken keresztül.

Üzenet küldése a Socketnek.IO

Ideje, hogy az eddig egyszerű ChatService szolgáltatásunkat kibővítsük egy olyan lehetőséggel, amellyel üzenetet küldhetünk a szervernek:

Hogy ez működjön, használnunk kell sendMessage() az AppComponentünkből:

Végül adjunk a felhasználónak egy egyszerű szövegbevitelt és egy gombot, hogy üzenetet küldhessen:

Hogy mindez működjön, figyelnünk kell a szerveren az ‘new-message’ eseményre, amelyet a ChatService-ből bocsátottunk ki:

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

Most az indexünk.js így néz ki:

Ha szeretnél játszani a kóddal, megtalálod a GitHub repómban – rxjs-chat.

Kommunikáció más felhasználókkal

Hogy az üzenetünket továbbítsuk más felhasználóknak, csak annyit kell tennünk, hogy a ‘new-message’ eseményhívásunk console.log(message) belső részét io.emit(message)-re módosítjuk:

És mit csinál az io.emit()? Egyszerűen fogalmazva küld egy eseményt mindenkinek, aki csatlakozik a szerverhez.

Kommunikáljunk a szerverünkkel a ChatService-en keresztül. Erre a célra egy új metódust adunk a szolgáltatásunkhoz – getMessages. Ez egy Observable-t fog visszaadni, amit a Observable.create() metódussal fogunk létrehozni. Minden alkalommal, amikor a socket új üzenetet kap, az observer.next() segítségével továbbítjuk azt a megfigyelőknek.

Ezután feliratkozunk erre az Observable-re az AppComponentünkből:

Elkészítünk egy új messages array-t, ahol a szervertől kapott üzeneteket fogjuk tárolni. Ezeket az üzeneteket kell majd megjelenítenünk a sablonunkban. Ez az ngFor tökéletes felhasználási esete: