Develop a chatroom using Ionic3, socket.io and Nodejs
Socket.io
Socket.io is a Javascript library that enables real-time, bidirectional and event-based communication.
Sometimes we hear that socket.io implements a web socket communication but is NOT true.
Socket.io uses the WebSocket protocol to provide the interface. Generally, it is divided into two parts, both WebSocket vs Socket.io are event-driven libraries
- Client Side: it is the library that runs on client side
- Server Side: it is the library for Node.js
Server Side
mkdir chatserver
cd chatserver
touch index.js
// index.js
let app = require('express')();
let http = require('http').Server(app);
let io = require('socket.io')(http);
io.on('connection', (socket) => {
socket.on('disconnect', function(){
io.emit('users-changed', {user: socket.nickname, event: 'left'});
});
socket.on('set-nickname', (nickname) => {
socket.nickname = nickname;
io.emit('users-changed', {user: nickname, event: 'joined'});
});
socket.on('add-message', (message) => {
io.emit('message', {text: message.text, from: socket.nickname, created: new Date()});
});
});
var port = process.env.PORT || 3001;
http.listen(port, function(){
console.log('listening in http://localhost:' + port);
});
npm install --save express socket.io
npm init
node index.js
Client Side
Let's start a chatroom on Ionic
git clone https://github.com/texano00/ionic3-chat-socketio.git
cd ionic3-chat-socketio
npm i
ionic serve // or ionic cordova run android
Focus on socket.io usage
import { Component, ViewChild } from '@angular/core';
import {
IonicPage,
ToastController,
AlertController,
Content
} from 'ionic-angular';
import { Socket } from 'ng-socket-io';
import { Observable } from 'rxjs/Observable';
import { FormControl, FormBuilder } from '@angular/forms';
@IonicPage()
@Component({
selector: 'page-chat-room',
templateUrl: 'chat-room.html'
})
export class ChatRoomPage {
@ViewChild(Content) content: Content;
messages = [];
nickname = '';
messageForm: any;
chatBox: any;
constructor(
private socket: Socket,
private toastCtrl: ToastController,
private alertCtrl: AlertController,
public formBuilder: FormBuilder
) {
this.messageForm = formBuilder.group({
message: new FormControl('')
});
this.chatBox = '';
this.presentPrompt().then((nickname: string) => {
this.nickname = nickname;
// connect to socket.io local server
this.socket.connect();
// send 'set-nickname' event to socket.io server
this.socket.emit('set-nickname', this.nickname);
this.getMessages().subscribe(message => {
this.messages.push(message);
this.scrollToBottom();
});
this.getUsers().subscribe(data => {
let user = data['user'];
if (data['event'] === 'left') {
this.showToast('User left: ' + user);
} else {
this.showToast('User joined: ' + user);
}
});
});
}
public sendMessage(message: string): void {
if (!message || message === '') return;
// send 'add-message' event to socket.io server
this.socket.emit('add-message', { text: message });
this.chatBox = '';
}
getMessages(): Observable<{}> {
let observable = new Observable(observer => {
this.socket.on('message', data => {
// update observable when the 'message' event is sent from the server
observer.next(data);
});
});
return observable;
}
getUsers(): Observable<{}> {
let observable = new Observable(observer => {
// update observable when the 'users-changed' event is sent from the server
this.socket.on('users-changed', data => {
observer.next(data);
});
});
return observable;
}
ionViewWillLeave(): void {
this.socket.disconnect();
}
showToast(msg: string): void {
let toast = this.toastCtrl.create({
message: msg,
duration: 2000
});
toast.present();
}
presentPrompt(): Promise<string> {
return new Promise((resolve, reject) => {
let alert = this.alertCtrl.create({
title: 'Nickname',
inputs: [
{
name: 'nickname',
placeholder: 'doretta'
}
],
buttons: [
{
text: 'Random',
role: 'cancel',
handler: data => {
resolve('random_' + Math.round(Math.random() * 100));
}
},
{
text: 'Go on',
handler: data => {
resolve(data.nickname);
}
}
]
});
alert.present();
});
}
scrollToBottom() {
setTimeout(() => {
this.content.scrollToBottom();
}, 100);
}
}
Links
- Ionic full source -> https://github.com/texano00/ionic3-chat-socketio
- Avatars are from http://avatars.adorable.io