Chat Application with Angular and Socket.IO
- Introduzione
- Socket.IO server setup
- Imposta la struttura delle cartelle
- Installazione di pacchetti locali
- Collegamento a Socket.IO
- Creazione del servizio per la comunicazione con il server
- Aggiungere il servizio ai provider del modulo
- Iniezione del servizio nel nostro componente
- Inviare un messaggio a Socket.IO
- Comunicare con altri utenti
Introduzione
Utilizzeremo RxJS, Angular, express (Node.js) &Socket.IO per fare una chat application. Avremo modo di vedere quanto possa essere utile RxJS in questo scenario. Allo scopo di rendere le cose lisce e facili, useremo Angular CLI per generare la struttura di base del client e ottenere un boilerplate per la più semplice applicazione Angular funzionante. Sul back-end useremo Node.js con express e Socket.IO. Il ragionamento dietro a questo è che Socket.IO è molto facile da impostare e lavorare. Inoltre, fornisce librerie sia lato server che lato client. Socket.IO usa principalmente il protocollo WebSocket per abilitare la comunicazione bidirezionale in tempo reale.
Se vuoi saltare direttamente alla parte in cui usiamo RxJS per gestire i messaggi di chat clicca qui.
Iniziamo!
Socket.IO server setup
Se non avete installato Angular CLI potete installarlo abbastanza facilmente:
npm i -g @angular/cli
Imposta la struttura delle cartelle
Per mantenere le cose pulite creeremo una nuova cartella rxjs-chat per il nostro piccolo progetto. Dovrebbe servire come cartella principale per le applicazioni Angular e Socket.IO.
Creiamo un’applicazione Angular di base usando Angular CLI. Nella cartella del nostro progetto lanciate il vostro terminale preferito ed eseguite il seguente comando:
ng new rxjs-chat
Dategli un po’ di tempo. Dopo aver finito di creare la struttura di base e di installare i pacchetti npm, rinomineremo la cartella del progetto Angular appena creata in client. Dopo di che, nella stessa cartella principale creiamo la cartella server per il nostro server Socket.IO. Ora abbiamo due cartelle all’interno della nostra cartella rxjs-chat:
- client – app client Angular
- server – presto sarà il server Socket.IO di Node
Installazione di pacchetti locali
Nella cartella server genereremo il file package.json eseguendo il seguente comando:
npm init -y
Dopo di che installeremo le nostre dipendenze e le salveremo in package.json:
npm install express socket.io --save
Nella stessa cartella creeremo il file index.js per la nostra app server. Il contenuto del file dovrebbe essere il seguente:
Creiamo un’istanza di express e la memorizziamo nella variabile app
. Dopo di che creiamo il server con il modulo http
. Poi passiamo express
al metodo http.Server()
. Express servirà come gestore per le richieste al nostro server. In cambio otteniamo l’istanza del server che memorizziamo nella variabile server
.
Nelle prossime due linee di codice leghiamo il socket.IO con il nostro http server:
let socketIO = require('socket.io');
let io = socketIO(server);
node index.js
Collegamento a Socket.IO
Abbiamo un server in esecuzione sulla porta 3000. Ora è il momento di vedere come possiamo connetterci al server dalla nostra app Angular. Per questo avremo bisogno di installare la libreria client Socket.IO. Eseguiremo il seguente comando nella nostra cartella client:
npm install socket.io-client --save
Mentre ci siamo eseguiamo l’app Angular tramite Angular CLI:
ng serve -o
Ora abbiamo la nostra app in esecuzione. Possiamo vedere che il nostro browser predefinito ha appena aperto una nuova scheda che punta a localhost. Ecco perché abbiamo usato l’argomento -o
per aprire il browser.
Creazione del servizio per la comunicazione con il server
Lo chiamerò chat.service.ts app.chat.service.ts e lo metterò dentro la cartella src. Il servizio sarà il più semplice possibile per ora:
Aggiungere il servizio ai provider del modulo
Inoltre, aggiungiamo il nostro ChatService alla lista dei provider all’interno di AppModule nel file app.module.ts:
Iniezione del servizio nel nostro componente
Finalmente, stiamo per importare e usare il servizio all’interno del nostro app.component.ts:
import { ChatService } from './app.chat.service';
E inietteremo il ChatService nel nostro costruttore:
constructor(chatService: ChatService) { }
Come risultato abbiamo il seguente file:
Se tutto è andato come previsto dopo aver salvato le modifiche dovresti vedere il messaggio ‘user connected’ nel terminale dove hai avviato node app:
$ node index.js
started on port: 3000
user connected
Dunque, possiamo dire che siamo finalmente riusciti a connetterci al nostro server Socket IO. Ora è il momento di inviare effettivamente dei dati tramite gli eventi Socket IO.
Inviare un messaggio a Socket.IO
È ora di migliorare il nostro finora semplice ChatService con un’opzione per inviare un messaggio al server:
Perché questo funzioni dobbiamo usare sendMessage()
dal nostro AppComponent:
Finalmente, forniamo all’utente un semplice input di testo e un pulsante per poter inviare un messaggio:
Perché tutto questo funzioni dobbiamo ascoltare sul server l’evento ‘new-message’ che abbiamo emesso dal ChatService:
socket.on('new-message', (message) => {
console.log(message);
});
Ora il nostro index.js assomiglia a questo:
Se volete giocare con il codice potete trovarlo sul mio repo GitHub – rxjs-chat.
Comunicare con altri utenti
Per far sì che il nostro messaggio venga trasmesso ad altri utenti tutto quello che dobbiamo fare è cambiare il console.log(message)
interno del nostro callback dell’evento ‘new-message’ in io.emit(message)
:
E cosa fa io.emit()? In parole povere invia un evento a tutti quelli connessi al server.
Comunichiamo con il nostro server tramite ChatService. Aggiungeremo un nuovo metodo al nostro servizio per questo scopo – getMessages
. Restituirà un Observable che creeremo con il metodo Observable.create()
. Ogni volta che il socket riceve un nuovo messaggio useremo observer.next() per inoltrarlo agli osservatori.
Dopo di che ci iscriveremo a questo Observable dal nostro AppComponent:
Abbiamo creato un nuovo messages
array dove memorizzeremo i messaggi ricevuti dal server. Dovremo mostrare questi messaggi nel nostro template. Questo è un caso d’uso perfetto per ngFor:
.