Як створити додаток для чату в режимі реального часу в 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/