Как да създадем приложение за чат в реално време в Node.js с помощта на Express, Mongoose и Socket.io

В този урок ще използваме платформата Node.js, за да изградим приложение за чат в реално време, което незабавно изпраща и показва съобщения на получател без опресняване на страницата. За да постигнем това, ще използваме JavaScript рамката Express.js и библиотеките Mongoose и Socket.io.

Преди да започнем, нека да разгледаме набързо основите на Node.js

Node.js

Node.js е среда за изпълнение на JavaScript с междуплатформена платформа с отворен код, която изпълнява JavaScript код извън браузъра. Най-важното предимство на използването на Node е, че можем да използваме JavaScript както като преден, така и като заден език.

Както знаем, JavaScript се използваше предимно за скриптове от страна на клиента, при което скриптове бяха вградени в HTML на уеб страница и се стартираха от страна на клиента от JavaScript механизъм в уеб браузъра на потребителя.

Node.js позволява на разработчиците да използват JavaScript за писане на инструменти за команден ред и за скриптове от страна на сървъра - стартиране на скриптове от страна на сървъра за създаване на динамично съдържание на уеб страница, преди страницата да бъде изпратена до уеб браузъра на потребителя.

За да инсталирате възел:

//nodejs.org/en/download/

Въпреки че възелът е с една нишка, все пак е по-бързо да се използват асинхронни функции. Например Node може да обработва други неща, докато файлът се чете от диска, или докато чака HTTP заявка да завърши. Асинхронното поведение може да бъде реализирано чрез обратно извикване. Също така JavaScript работи добре с JSON и No-SQL бази данни.

NPM модули

Nodejs позволява модулите на библиотеките да бъдат включени в приложението. Тези модули могат да бъдат дефинирани от потребителя или модули на трети страни.

Модулите на трети страни могат да бъдат инсталирани чрез следната команда:

npm install module_name

и инсталираните модули могат да се използват с помощта на функцията require () :

var module = require(‘module_name’)

В приложенията на Node ще използваме файл package.json, за да поддържаме версиите на модула. Този файл може да бъде създаден от тази команда:

npm init

и пакетите трябва да бъдат инсталирани, както следва:

npm install -s module_name

Има много рамки, които могат да бъдат добавени като модули към нашето приложение Node. Те ще бъдат обяснени допълнително при необходимост.

Обикновено приложение за чат

Приложението трябва да позволява на много потребители да чат заедно. Съобщенията трябва да се актуализират, без да се опреснява страницата. За простота ще избягваме частта за удостоверяване.

Можем да започнем, като създадем нова директория на проекта и преминем в нея. След това можем да инициираме нашия проект чрез следната команда:

npm init

Това ще ни подкани да въведем подробности за нашия проект.

След това ще бъде създаден файл package.json :

{ “name”: “test”, “version”: “1.0.0”, “description”: “”, “main”: “index.js”, “scripts”: { “test”: “echo \”Error: no test specified\” && exit 1" }, “author”: “”, “license”: “ISC” }

Нашата директория с приложения вече е настроена.

Първото нещо, което трябва да създадем, е сървър. За да създадем това, ще използваме рамка на име Express.

Express.js

Express.js или просто Express е рамка за уеб приложения за Node.js. Express предоставя богат набор от функции за уеб и мобилни приложения. Express предоставя тънък слой от основни функции на уеб приложението, без да закрива функциите на Node.js.

Ще инсталираме Express.js, като използваме следната команда:

npm install -s express

Във файла package.json ще бъде добавен нов ред:

dependencies”: { “express”: “⁴.16.3” }

След това ще създадем файл server.js .

В този файл трябва да изискваме Express и да създадем препратка към променлива от екземпляр на Express. Статично съдържание като HTML, CSS или JavaScript може да се обслужва с помощта на express.js:

var express = require(‘express’); var app = express();

и можем да започнем да слушаме порт, използвайки кода:

var server = app.listen(3000, () => { console.log(‘server is running on port’, server.address().port); });

Сега трябва да създадем HTML файл index.html, който показва нашия потребителски интерфейс. Добавих bootstrap и JQuery cdn.

//index.html    

Send Message

Send

Моля, обърнете внимание, че празният таг < ; / script> ще бъде мястото, където ще напишем JavaScript кода от страна на клиента.

За да кажем на Express това, ще използваме статичен файл. Ще добавим нов ред в server.js:

app.use(express.static(__dirname));

Можем да стартираме server.js с помощта на командата

node ./server.js

или пакет, наречен nodemon , така че промените, направени в кода, ще бъдат автоматично открити. Ще изтеглим nodemon с помощта на командата

npm install -g nodemon

-g - глобален, така че да е достъпен във всички проекти.

Ще стартираме кода с помощта на командата

nodemon ./server.js

Ако отидете на localhost: 3000, можем да видим индексния файл:

Сега, когато сървърът ни работи и работи, трябва да създадем нашата база данни. За това приложение ще разполагаме с база данни No-SQL и ще използваме Mongodb . Настройвам си mongodb в mlab.com . Нашата база данни ще съдържа една колекция, наречена съобщения с имена на полета и съобщение.

За да свържем тази база данни с приложението, ще използваме друг пакет, наречен Mongoose .

Мангуста

Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment. Mongoose can be installed using the command

npm install -s mongoose

Inside server.js we will require mongoose:

var mongoose = require(‘mongoose’);

And we will assign a variable, the URL of our mlab database:

var dbUrl = ‘mongodb://username:[email protected]:57981/simple-chat’

Mongoose will connect to the mlab database with the connect method:

mongoose.connect(dbUrl , (err) => { console.log(‘mongodb connected’,err); })

And we will be defining our message model as

var Message = mongoose.model(‘Message’,{ name : String, message : String})

We can implement the chat logic now. But before that there is one more package that needs to be added.

Body-Parser

Body-Parser extracts the entire body portion of an incoming request stream and exposes it on req.body. The middleware was a part of Express.js earlier, but now you have to install it separately.

Install it using the following command:

npm install -s body-parser

Add the following codes to server.js:

var bodyParser = require(‘body-parser’) app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false}))

Routing

Routing refers to how an application’s endpoints (URIs) respond to client requests. You define routing using methods of the Express app object that correspond to HTTP methods: app.get() to handle GET requests and app.post() to handle POST requests.

These routing methods specify a callback function (sometimes called “handler functions”) called when the application receives a request to the specified route (endpoint) and HTTP method. In other words, the application “listens” for requests that match the specified routes and methods, and when it detects a match, it calls the specified callback function.

Now we need to create two routes to the messages for our chat to work.

Inside server.js:

get : will get all the message from database

app.get('/messages', (req, res) => { Message.find({},(err, messages)=> { res.send(messages); }) })

post : will post new messages created by the user to the database

app.post('/messages', (req, res) => { var message = new Message(req.body); message.save((err) =>{ if(err) sendStatus(500); res.sendStatus(200); }) })

In order to connect these routes to the front end we need to add the following code in the client side script tag in the index.html:

$(() => { $("#send").click(()=>{ sendMessage({ name: $("#name").val(), message:$("#message").val()}); }) getMessages() }) function addMessages(message){ $(“#messages”).append(` 

${message.name}

${message.message}

`) } function getMessages(){ $.get(‘//localhost:3000/messages', (data) => { data.forEach(addMessages); }) } function sendMessage(message){ $.post(‘//localhost:3000/messages', message) }

Here the sendMessage is used to invoke the post route of the messages, and save a message sent by the user. The message is created when a user clicks the send button.

Similarly the getMessage is used to invoke the get route of messages. This will get all the messages saved in the database and will be appended to the messages div.

The only issue now is that there is no way for the client to know if the server is updated. So each time we post a message we need to refresh the page to see the new messages.

To solve this we can add a push notification system that will send messages from server to client. In Node.js we use socket.io.

Socket.io

Socket.IO is a JavaScript library for realtime web applications. It enables realtime, bi-directional communication between web clients and server. It has two parts: a client-side library that runs in the browser, and a server-side library for Node.js. Socket.io enables real-time bidirectional event-based communication.

To install socket.io:

npm install -s socket.io

we also need an HTTP package for Socket.io to work:

npm install -s http

Add the following code to server.js:

var http = require(‘http’).Server(app); var io = require(‘socket.io’)(http);

And we can create a connection:

io.on(‘connection’, () =>{ console.log(‘a user is connected’) })

In the index.html add the following tag:

Now we need to create an emit action when a message is created in server.js. So the post route becomes this:

app.post('/messages', (req, res) => { var message = new Message(req.body); message.save((err) =>{ if(err) sendStatus(500); io.emit('message', req.body); res.sendStatus(200); }) })

And in the client side script tag in index.html, add the following code:

var socket = io(); socket.on(‘message’, addMessages)

So each time a message is posted, the server will update the messages in the message div.

Great!!

This is very basic application that we can create in Node.js. There is lot of scope for improvement. The finished code can be found in //github.com/amkurian/simple-chat

server.js

var express = require('express'); var bodyParser = require('body-parser') var app = express(); var http = require('http').Server(app); var io = require('socket.io')(http); var mongoose = require('mongoose'); app.use(express.static(__dirname)); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})) var Message = mongoose.model('Message',{ name : String, message : String }) var dbUrl = 'mongodb://username:[email protected]:57981/simple-chat' app.get('/messages', (req, res) => { Message.find({},(err, messages)=> { res.send(messages); }) }) app.get('/messages', (req, res) => { Message.find({},(err, messages)=> { res.send(messages); }) }) app.post('/messages', (req, res) => { var message = new Message(req.body); message.save((err) =>{ if(err) sendStatus(500); io.emit('message', req.body); res.sendStatus(200); }) }) io.on('connection', () =>{ console.log('a user is connected') }) mongoose.connect(dbUrl ,{useMongoClient : true} ,(err) => { console.log('mongodb connected',err); }) var server = http.listen(3001, () => { console.log('server is running on port', server.address().port); });

Hope this was helpful in understanding some basic concepts.

Some useful links

Socket.IO

SOCKET.IO 2.0 IS HERE FEATURING THE FASTEST AND MOST RELIABLE REAL-TIME ENGINE ~/Projects/tweets/index.js var io =…socket.ioExpress - Node.js web application framework

Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and…expressjs.com

//mongoosejs.com/