Socket Programming in AngularJS 2 - Building a simple chat application with Socket.io and RxJS
In my previous article, I showed you how two or more servers can access each other through a common URL (or REST API). I used the Firebase server that is connected with our localhost server on our hard-drive, and then I implemented HTTP's GET and POST methods. Behind the HTTP, the sockets are used that allow the networks to communicate with each other through the operating system’s APIs. HTTP is used at the application level protocol in the OSI model, so HTTP itself can't be used to transfer information from/to a remote end point (we will see more about the OSI layer later).
Socket programming is used to make the sockets at the end of the client and the server and enable the communication between different networks (let's say a client and a server). It takes the help of TCP (Transmission Control Protocol), which is a reliable, stream oriented protocol. But, TCP itself doesn't contain any API, as it's just a protocol. So, for that, there are various APIs that can be used for TCP, including the older Berkeley sockets, that provided the APIs for both internet sockets and Unix domain sockets.
Even though, AngularJS 2's RxJS components (and Observables with HTTP requests) have pretty much reduced the need for the socket programming, we still need to use the sockets from time to time, especially when we need to deal with the server/transport side directly, in case some language-specific protocol is required or we need to access the raw bytes. Socket.io is normally used for writing sockets in AngularJS 2, which we will cover later in the article.
In this article, I am going to show you what is socket programming, and how it is implemented in AngularJS 2 through Socket.io and RxJS. We will also create a chat application. Let's get started!
Socket Programming in AngularJS 2 - Building a simple chat application with Socket.io and RxJS
What is socket programming?
In order to understand the sockets, let's first understand the OSI model. The OSI model talks about the standard reference model for how the applications can or should communicate over the network. This is standard in the sense that if any new telecommunication device is invented, then it needs to follow this model, as it abstracts the internal structure of the technology, which means that despite the difference in the internal feature of two devices, if they implement the OSI model, then they can successfully communicate with each other.
For example, modern PCs use the same architecture despite the different specifications, or the Android smartphones use the same OS despite different internal features. This allows for communication between different devices. In a similar way, telecommunication devices need to follow the same model in order to communicate with each others.
The OSI model contains 7 levels, but we won't go into details about the layers, you can read more about it from here (https://en.wikipedia.org/wiki/OSI_model). Its transport layer is used to enable the transfer between the networks. The HTTP mostly uses TCP-based protocol for the transfer, and so this is the place where the socket programming comes, because you need to write the code to communicate between APIs and your application.
HTTP works on top of the socket (remember the old GET and POST requests?). HTTP is session-less which means that the connection is closed once you send GET and POST requests (although HTTP 1.1 seems to allow the connection to remain open). But, as I mentioned earlier, we also need to communicate with low-level stuff at times, for example, sending and receiving the raw bytes, so we use sockets for that purpose.
HTTP is also platform-neutral technology, because it abstracts the low-level details, so the same mechanism can be used in every network. Socket programming is used where the system has a language specific protocol, or in other words for the stuff that is necessary to operate with low-level details.
Therefore, we can conclude that socket programming allows the communication between several networks through the common API methods, such as, Sockets(), Bind(), Listen(), etc.
How sockets are implemented in AngularJS 2
We know that AngularJS 2 uses Observables for the synchronous processing through the help of RxJS library. I won't get into the details what Observables are because I have covered it before in my previous article. There is the famous library called Socket.io that enables realtime, bi-directional communication between web clients and servers through its cool API atuferes, such as, on() and emit() methods. It has both the parts for the client side (that runs in the browser) and server side (for the node.js). You can read more about its API from here (http://socket.io/docs/#), but for now, just know that we will be using Socket.io with our HTTP server through the help of express library.
So, let's create a simple chat application!
Creating the server
We will use the Socket.io (through the help of express) to create our backend server which will receive and sent the data to our other networks (servers). This is the basic requirements of any chat application.
Create a new folder "server" and create a file "index.js" and paste the following content:
index.js
'use strict';
let app = require('express')();
let http = require('http').Server(app);
let io = require('socket.io')(http);
io.on('connection', (socket) => {
console.log('The user is connected');
socket.on('disconnect', function(){
console.log('The user is disconnected');
});
socket.on('add-message', (message) => {
io.emit('message', {type:'new-message', text: message});
});
});
http.listen(5000, () => {
console.log('started on port 5000');
});
Here, I am using the on() method that tells the server what to do when the particular event occurs. The emit() method sends the event or a message.
In the same folder, create a new file "package.json" and paste the following content:
package.json
{
"name": "socket-io-server",
"version": "0.0.1",
"description": "socket.io server",
"dependencies": {
"express": "^4.13.4",
"socket.io": "^1.4.6"
}
}
Here, I have added the socket.io and express to the dependencies list. Now, you need to install the modules as well:
$npm install --save socket.io
$npm install --save express
Once the modules are installed, do the "node index.js" to run the server. You will see the "The user is connected" on the console screen!
Now we will code the client side.
Creating the client
For the client, we will be using the AngularJS 2 through CLI. Create a new project "AngularJS2-Sockets":
$ng new AngularJS2-Sockets
Now we need to install the Socket.io library:
$npm install socket.io-client --save
We need to install the typing version as well in order for everything to work properly:
$npm install @types/socket.io-client --save
Now the time to write the actual code!
We will be using this (http://socket.io/get-started/chat/) template for our chat application. The idea is that the server receives the text from the clients (we will use two clients on separate browser tabs) and the results are transferred back to the clients which will be shown on the front-page on both the clients, suggesting that the results are being synchronized! Think of this application an example of telephone working!
Let's first create a chat component:
$ng g component chat
In the "chat" folder, create a new file "chat.service.ts" and paste the following content:
chat.service.ts
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
import * as io from 'socket.io-client';
export class ChatService {
// Our localhost address that we set in our server code
private url = 'http://localhost:5000';
private socket;
sendMessage(message){
// Make sure the "add-message" is written here because this is referenced in on() in our server
this.socket.emit('add-message', message);
}
getMessages() {
let observable = new Observable(observer => {
this.socket = io(this.url);
this.socket.on('message', (data) => {
observer.next(data);
});
return () => {
this.socket.disconnect();
};
})
return observable;
}
}
We will be using this service in our chat component. Copy the following content to "chat.component.ts":
chat.component.ts
import { Component, OnInit,OnDestroy } from '@angular/core';
import { ChatService } from './chat.service';
@Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.css'],
providers: [ChatService]
})
export class ChatComponent implements OnInit, OnDestroy {
messages = [];
connection;
message;
constructor(private chatService:ChatService) {}
sendMessage(){
this.chatService.sendMessage(this.message);
this.message = '';
}
ngOnInit() {
this.connection = this.chatService.getMessages().subscribe(message => {
this.messages.push(message);
})
}
// Let's unsubscribe our Observable
ngOnDestroy() {
this.connection.unsubscribe();
}
}
Here, I have first declared the "socket" variable, and then I have connected it to the localhost server where the Socket.io server side is running. We have defined a function sendMessage() that uses the socket.emit() -- which allows you to emit custom events on the server and client, through it we will send the message to the server, and the server will decide through socket.on() which actions need to be performed. These two functions are the building blocks of the socket programming in Socket.io!
Now, we need the input field and the button to send the message. Copy the following content to "chat.component.html":
chat.component.html
<form action="">
<input [(ngModel)]="message" [ngModelOptions]="{standalone: true}" /><button (click)="sendMessage()">Send</button>
</form>
<div id="messages" *ngFor="let message of messages">
<div id="item">
{{message.text}}
</div>
</div>
Now, for the syling, copy the following content to "chat.component.css":
chat.component.css
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages #item { padding: 5px 10px; }
#messages #item { background: #eee; }
We need to use this component in our application, so let's add the selector "<app-chat></app-chat>" to our "app.component.html":
app.component.html
<app-chat></app-chat>
And that's it! Now, do the "ng serve" in the root folder. You will see the text field and the send button at the bottom. Try giving some input and pressing the send. You will see the results on the screen (that is rendered on a grey background!) that is received from the server side! Try opening the same localhost address to a new tab and then send a message from one client, and you will see that it will be received on the other client side!
You can see the whole source code here (https://github.com/danyalzia/AngularJS2-Sockets).
Socket.io blog contains several interesting posts (http://socket.io/blog/introducing-socket-io-1-0/#).
Summary
So far we have learned the following things:
- Socket programming is used to enable the communication between the networks and allow dealing with low levels of networking.
- io is used to create sockets for the communication between client and a server, which can be manipulated through common HTTP protocols.
- We use Observables to pass several on() messages to the sockets
Conclusion
Thus, so far, you can see that I have highlighted what socket programming is and what it is not, and how to use the socket programming in AngularJS 2. I have provided an awesome chat application that shows the sophistication of the Socket.io and RxJS library, you can use this project as the basis for your next awesome applications!
If you have any questions, then please ask in the comment section below!
If you liked this article, why not share it with people on social media networks?
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment