Angular 9/8/7 Realtime Chat Example with Node.js, Socket.io and WebSocket
In this tutorial, we'll learn how to build a real-time app with Angular 9/8, Socket.IO, and Node.js.
Socket.IO primarily uses the WebSocket protocol to enable real-time bidirectional communication.
WebSocket is the internet protocol that allows for full duplex communication between a server and clients. The server may send data to a client without the client initiating a request.
You can also read how to build a complete chat app with a hosted service like Pusher Chatkit or PubNub Chat in Building a Chat App with TypeScript/Node.js, Ionic 5/Angular 9 & PubNub/Chatkit
Let's see how to create a simple chat server with socket.io and websockets.
Step 1 -- Creating the Chat Server
Open a new command-line interface and run the following commands to create your server project:
$ mkdir node-realtime-server
$ cd node-realtime-server
$ mkdir src
$ npm init
$ npm install express socket.io @types/socket.io --save
Next, navigate inside the src/
folder, and create a new file called index.js
using the following commands:
$ mkdir src
$ touch index.js
Open the src/index.js
file and start by adding the following code:
const express = require('express')
const app = express();
const http = require('http');
const server = http.Server(app);
const socketIO = require('socket.io');
const io = socketIO(server);
const port = process.env.PORT || 3000;
io.on('connection', (socket) => {
console.log('user connected');
});
server.listen(port, () => {
console.log(`started on port: ${port}`);
});
We simply create an express server and use socket.io to add realtime support. Socket.io implements WebSockets with extra features like fallback for older browsers that do not support the realtime protocol.
We create an instance of express and store it into app
variable. After that we create server with http
module. Then we pass express
to http.Server()
method. Express will serve as the handler for requests to our server. In return we get the instance of server which we store in server
variable.
Next, we listen for the connection
event of socket.io and we display the user connected
message once a user has connected to our real-time server.
Next, we need to listen for the new_message
event, and send the message back sent by a user to all connected users:
io.on('new-message', (message) => {
io.emit(message);
});
Finally, we run the server and start listenning on a specified port or 3000.
Let's now run our server by running the following command:
$ node src/index.js
Step 2 -- Initializing the Angular 9 Project
Open a new command-line interface and run the following command to initialize a new project:
$ ng new angular-realtime-app
You will be prompted if you would like to add routing to your project - You need to answer by Y to set up the router. For the stylesheets format, let's go with CSS.
Next, let's start a live-reload development server using the following commands:
$ cd ./angular-realtime-app
$ ng serve
The server will be running at the http://localhost:4200
address.
Step 3 -- Installing the Socket.IO Wrapper
Next, navigate inside your project's folder and install ngx-socket-io
which is a wrapper for socket.io in Angular:
$ cd angular-realtime-app
$ npm install ngx-socket-io --save
Step 4 -- Importing SocketIoModule
Open the src/app/app.module.ts
file and start by adding the following imports:
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
Next, define a configuration object for configuring socket.io as follows:
const config: SocketIoConfig = { url: 'http://localhost:3000', options: {} };
Next, include SocketIoModule
in the imports
array:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
SocketIoModule.forRoot(config)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
After saving the file, you will be connected to the realtime server. You should see a user connected message in the terminal.
Step 5 -- Creating an Angular Chat Service
Open the src/app/message.ts
file and add the following code:
export class Message {
id: string;
body: string;
}
Next, run the following command to generate a service:
$ ng generate service chat
Open the src/app/chat.service.ts
file and update it as follows:
import { Injectable } from '@angular/core';
import { Socket } from 'ngx-socket-io';
import { Message } from '../message';
@Injectable({
providedIn: 'root'
})
export class ChatService {
constructor(private socket: Socket) { }
}
We simply import and inject the Socket
service via the constructor.
Next, define the following method which can be used to send a new message to the real-time server:
public sendMessage(message) {
this.socket.emit('new-message', message);
}
Next, we need to define a getMessages
method for getting the messages:
public getMessages = () => {
return Observable.create((observer) => {
this.socket.on('new-message', (message) => {
observer.next(message);
});
});
}
We use the Observable.create()
method to create and return an observable
This will allow us to notify all observers when the socket receives a new message.
Step 6 -- Creating the Chat UI
Next, let's create the chat UI of our application. Let's keep it simple and use the app component for displaying the UI.
Open the src/app/app.component.ts
file and update it as follows:
import { Component } from '@angular/core';
import { ChatService } from '../chat.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
newMessage: string;
messageList: string[] = [];
constructor(private chatService: ChatService) {
}
sendMessage() {
this.chatService.sendMessage(this.newMessage);
this.newMessage = '';
}
ngOnInit() {
this.chatService
.getMessages()
.subscribe((message: string) => {
this.messageList.push(message);
});
}
}
Open the src/app/app.component.html
file and update it as follows:
<div *ngFor="let message of messageList">
</div>
<input [(ngModel)]="newMessage" (keyup)="$event.keyCode == 13 && sendMessage()" />
<button (click)="sendMessage()">Send Message</button>
Step 8 -- Serving the Chat Front-End
Let's now run the front-end server using the following command:
$ cd angular-realtime-app
$ ng serve
You can test the chat application by opening more than one browser and navigating to the http://localhost:4200
address.
Conclusion
In this tutorial, we have created a real-time chat example with Angular 9, Node.js, Socket.IO and WebSockets.
-
Date: