Chat Integration with Socket.io in Angular

Angular Sep 16, 2022

Before a healthcare tech companies came into existence, we had to go to a hospital for consultation with a doctor. Several years ago, Halodoc has introduced a feature to get online consultation. It's easy, faster, and cheaper than offline consultation at the hospital. One of the features we have is chatting with doctors. With that feature, we can send text messages, audio, and video call to the doctor.

In this section, we will focus to create a simple chat message with socket.io in Angular. Here we will be developing a chat application using NodeJS as a server, Angular as a client, and socket.io for socket communication. Before we discuss further about socket.io we first should know about WebSocket to easily understand about socket.io.

What is WebSocket

WebSocket is bidirectional, a full-duplex protocol that is used in the same scenario of client-server communication, HTTP starts from ws:// or wss://. It is a stateful protocol, which means the connection between client and server will keep alive until it is terminated by either party (client or server). After closing the connection by either of the client and server, the connection is terminated from both ends.

When can a WebSocket be used:

  1. Real-time web application
  2. Online multiplayer Game
  3. Chat application
  4. Realtime notification

What is socket.io

Socket.IO is a library that enables low-latency, bidirectional and event-based communication between a client and a server. It is built on top of the WebSocket protocol and provides additional guarantees like fallback to HTTP long-polling or automatic reconnection.

Preparation

Before we start, please check if you have NodeJS and Angular installed. We will be using a Node.JS app(server) and a Angular app(Client) to demonstrate the use of Web Sockets.

// check node version
node -v

// check Angular version
ng --version

Create Node App

In our project folder, we have to create separate to be two sub folders:
- server
- client

Initialize npm in server directory

In server folder, we need to init the npm, this can be done by using npm init

npm init

This will be creating a package.json file in the server directory, and this will allow us to install npm packages in our project and create an index.js file.

Install express and socket.io

In server folder install this package

npm i express socket.io

Setting up socket server

create file name index.js inside server folder.

const app = require('express')();
const httpServer = require('http').createServer(app);
const io = require('socket.io')(httpServer, {
  cors: {origin : '*'}
});

const port = 3000;

io.on('connection', (socket) => {
  console.log('a user connected');

  socket.on('message', (message) => {
    console.log(message);
    io.emit('message', `${socket.id.substr(0, 2)}: ${message}`);
  });

  socket.on('disconnect', () => {
    console.log('a user disconnected!');
  });
});

httpServer.listen(port, () => console.log(`listening on port ${port}`));
index.js

Now we have a server that is listening on port 3000. The socket server is listening for a connection event. When the app is connected to this server, it will emit the connection events, and when the user leaves the page, the disconnect event will be called. After the message event is received by our server, it will send the message to all our users who connected with the connection event and will receive the same message.

Setting up socket server

To start the server, we can easily running this command.

node .

Create Client with Angular

Initialize Angular app

Navigate to the client folder and run this command to create a new Angular app

ng new chat-application

You can replace the chat-application with any name for the Angular App name.

Install socket.io client

After creating the angular app, we need to install the socket.io package to help us to communicate between client and server.

npm i socket.io-client

Create a chat service

We can generate a new service stub using this command.

ng g s chat

and same as like above command, we can change the chat service name to any name. After generating the chat service it will create 2 new files inside the app folder, chat.service.ts and chat.service.spec.ts. Change the chat.service.ts file to be this:

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { io } from "socket.io-client";


@Injectable({
  providedIn: 'root',
})
export class ChatService {

  public message$: BehaviorSubject<string> = new BehaviorSubject('');
  constructor() {}

  socket = io('http://localhost:3000');

  public sendMessage(message: any) {
    console.log('sendMessage: ', message)
    this.socket.emit('message', message);
  }

  public getNewMessage = () => {
    this.socket.on('message', (message) =>{
      this.message$.next(message);
    });

    return this.message$.asObservable();
  };
}
chat.service.ts

In this file, we've already set up for the client to connect to our socket server running on port 3000.

Update app component file

After we generate the service and it's connected to our server now we can create a component that will be using the service that we've created above, and change the app.component.ts

import { Component } from '@angular/core';
import { ChatService } from './chat.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  newMessage = '';
  messageList: string[] = [];

  constructor(private chatService: ChatService){

  }

  ngOnInit(){
    this.chatService.getNewMessage().subscribe((message: string) => {
      this.messageList.push(message);
    })
  }

  sendMessage() {
    this.chatService.sendMessage(this.newMessage);
    this.newMessage = '';
  }
}
app.component.ts

Update the HTML file

<div *ngFor="let message of messageList">
  <li>
      {{message}}
  </li>
</div>

<input
  [(ngModel)]="newMessage"
  (keyup)="$event.keyCode == 13 && sendMessage()"
/>
<button (click)="sendMessage()">Send Message</button>
app.component.html

Start Angular app

It's the final step to developing this simple app, we just start the Angular app using this command:

ng serve

Conclusion

We have already built our chat app, but this app you may find some limitations here. It only supports one chat room or sends an individual message to a few people.

As next steps we can use database to store the messages and then get the previous message from database. Further more socket.io supports chat room and you can improve this app to create rooms and send message to specific room.

Join us

Scalability, reliability and maintainability are the three pillars that govern what we build at Halodoc Tech. We are actively looking for engineers at all levels and  if solving hard problems with challenging requirements is your forte, please reach out to us with your resumé at careers.india@halodoc.com.


About Halodoc

Halodoc is the number 1 all around Healthcare application in Indonesia. Our mission is to simplify and bring quality healthcare across Indonesia, from Sabang to Merauke. We connect 20,000+ doctors with patients in need through our Tele-consultation service. We partner with 3500+ pharmacies in 100+ cities to bring medicine to your doorstep. We've also partnered with Indonesia's largest lab provider to provide lab home services, and to top it off we have recently launched a premium appointment service that partners with 500+ hospitals that allow patients to book a doctor appointment inside our application. We are extremely fortunate to be trusted by our investors, such as the Bill & Melinda Gates Foundation, Singtel, UOB Ventures, Allianz, GoJek, Astra, Temasek and many more. We recently closed our Series C round and In total have raised around USD$180 million for our mission. Our team works tirelessly to make sure that we create the best healthcare solution personalised for all of our patient's needs, and are continuously on a path to simplify healthcare for Indonesia.

Irwin Pratajaya

Web SDE - Passionate about creating innovative and user-friendly web solutions and dedicated to delivering high-quality code