Click Below to subscribe

How to Integrate Socket.IO with Angular 2021

Socket.IO is the popular javascript library that helps us to create a real-time web application. With the help of it, we can manage the real-time, bidirectional and event-based communication between two applications. It works on every platform, browser or device, focusing equally on reliability and speed.

"socket.io enables full-duplex communication between the client and server"

Implementation:
Frontend: angular, ngx-socket-io
Backend: node.js (express), socket.io

Let's Start with Frontend.

1. Install @angular/cli package.

npm install -g @angular/cli

2.  after installation create a new project.

ng new client //client is project name

3. Install ngx-socket-io package in your project.

cd client
npm i ngx-socket-io

4. Open app.module.ts and import SocketIoModule.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';
import { environment } from 'src/environments/environment';
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';

const config: SocketIoConfig = {
	url: environment.socketUrl, // socket server url;
	options: {
		transports: ['websocket']
	}
}

@NgModule({
	declarations: [
		AppComponent 
	],
	imports: [
		BrowserModule,
		SocketIoModule.forRoot(config), 
	],
	providers: [],
	bootstrap: [AppComponent]
})
export class AppModule { }

Don't forget to define socketUrl property in environment.ts file. After backend implementation, we will update this property.

export const environment = {
  production: false,
  socketUrl: '' 
};

5. Create a services folder inside the src/app directory. after that create a socket service.

ng g s services/socket --skipTests=true

6. Open generated socket.service.ts and inject socket in the constructor.

import { Injectable } from '@angular/core';
import { Socket } from 'ngx-socket-io';  

@Injectable({
	providedIn: 'root'
})
export class SocketService {
	constructor(private socket: Socket) { }
}

7. Now create emitter and listeners in this service. 

import { Injectable } from '@angular/core';
import { Socket } from 'ngx-socket-io';  

@Injectable({
	providedIn: 'root'
})
export class SocketService {
	constructor(private socket: Socket) { }

	// emit event
	fetchMovies() {
		this.socket.emit('fetchMovies');
	} 

	// listen event
	onFetchMovies() {
		return this.socket.fromEvent('fetchMovies');
	}
}

8. Create a component(ListComponent).

ng g c components/pages/movies/list --skipTests=true

9. Import SockerService your component in list.component.ts and inject it. Now using SockerService we can emit and listen socket events

import { Component, OnInit } from '@angular/core'; 
import { SocketService } from 'src/app/services/socket.service';  

@Component({
	selector: 'app-list',
	templateUrl: './list.component.html',
	styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit { 

	constructor(
		private socketService: SocketService 
	) { }

	ngOnInit(): void { 
            // here we can use socket events and listeners using socketService
	} 
}

Backend:-

1. Install express-generator package.

npm install -g express-generator

2.  after installation create a new project.

express server --view=hbs //server is project name

Note:- you can use --no-view flag if you don't want to setup the view engine. 

3. Install socket.io package in your project.

cd server
npm i socket.io

4. create a socket folder in your project. inside this folder create an index.js file. and add the following code.

module.exports = (io) => {

    io.on('connection', socket => {

        console.log('new connection'); 
        
		socket.on('disconnect', () => console.log('disconnected')); 
		
	})
}

5. Now we need to attach io with the express server. so open app.js file. and import socket io and our socket handler. also, change the export statement as shown.

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

// require socket.io
const io = require('socket.io')(); //<------
require('./socket')(io)            //<------ 


module.exports = { app, io };      //<------ 

6. so now our app.js module exporting two objects. that's why we need to modify www file. placed inside the bin folder. see arrow in sample code 

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var { app, io } = require('../app');         //<-------------
var debug = require('debug')('server:server');
var http = require('http');

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Attach io with http server.
 */

io.attach(server);                             //<-------------

These two lines

var { app, io } = require('../app'); 
io.attach(server);

7. Now start your backend code

npm start

By default express code running on 3000. open http://localhost:3000 in the browser you will see express in the browser window.

Connect Backend with Frontend

1. Now in your frontend code open environment.ts file and modify socketUrl

export const environment = {
  production: false,
  socketUrl: 'http://localhost:3000'
};

2. Start the frontend

ng serve
ng s   // or using alias

 open http://localhost:4200 on the browser and check node server(express) terminal.

 you will see a new connection message by our console.log statement.

so our socket connection established successfully. now we can use emitter and listener using SocketService.

import { Component, OnInit } from '@angular/core';
import { BsModalService } from 'ngx-bootstrap/modal';
import { SocketService } from 'src/app/services/socket.service';
import { FormComponent } from '../form/form.component';
import { Movie } from 'src/app/interfaces/movie';

@Component({
	selector: 'app-list',
	templateUrl: './list.component.html',
	styleUrls: ['./list.component.css']
})
export class ListComponent implements OnInit {

	movies: Movie[] = [];

	constructor(
		private socketService: SocketService,
		private modalService: BsModalService
	) { }

	ngOnInit(): void {
		this.socketService.fetchMovies();
		this.socketService.onFetchMovies().subscribe((data: any) => this.movies = data)
	}

	handleModal(movie?: Movie) {
		this.modalService.show(FormComponent, { initialState: { movie } });
	}

	handleDelete(movie: Movie) {
        if(movie.id) {
            this.socketService.deleteMovie(movie.id);
        }
	}
}

Rooms:- https://socket.io/docs/v4/rooms

Emit Cheatsheet:- https://socket.io/docs/v4/emit-cheatsheet

Checkout my full Socket.IO CRUD example using mysql(sequelize).

https://github.com/ultimateakash/angular-socket.io

If you need any help, don't hesitate to comment below.

Thanks.

Leave Your Comment