Πώς να δημιουργήσετε μια εφαρμογή συνομιλίας σε πραγματικό χρόνο στο Node.js χρησιμοποιώντας Express, Mongoose και Socket.io

Σε αυτό το σεμινάριο, θα χρησιμοποιήσουμε την πλατφόρμα Node.js για να δημιουργήσουμε μια εφαρμογή συνομιλίας σε πραγματικό χρόνο που στέλνει και εμφανίζει μηνύματα σε έναν παραλήπτη αμέσως χωρίς ανανέωση σελίδας. Για να το επιτύχουμε, θα χρησιμοποιήσουμε το JavaScript framework Express.js και τις βιβλιοθήκες Mongoose και Socket.io.

Πριν ξεκινήσουμε, ας ρίξουμε μια γρήγορη ματιά στα βασικά του Node.js

Node.js

Το Node.js είναι ένα περιβάλλον εκτέλεσης JavaScript ανοιχτού κώδικα, μεταξύ πλατφορμών και εκτελεί κώδικα JavaScript εκτός του προγράμματος περιήγησης. Το πιο σημαντικό πλεονέκτημα της χρήσης του κόμβου είναι ότι μπορούμε να χρησιμοποιήσουμε το JavaScript ως γλώσσα front-end και back-end.

Όπως γνωρίζουμε, το JavaScript χρησιμοποιήθηκε κυρίως για δέσμες ενεργειών από την πλευρά του πελάτη, όπου τα σενάρια ενσωματώθηκαν σε HTML μιας ιστοσελίδας και εκτελέστηκαν από την πλευρά του πελάτη από μια μηχανή JavaScript στο πρόγραμμα περιήγησης ιστού του χρήστη.

Το Node.js επιτρέπει στους προγραμματιστές να χρησιμοποιούν JavaScript για τη σύνταξη εργαλείων γραμμής εντολών και για δέσμες ενεργειών από την πλευρά του διακομιστή - εκτέλεση σεναρίων από την πλευρά του διακομιστή για την παραγωγή δυναμικού περιεχομένου ιστοσελίδας πριν από την αποστολή της σελίδας στο πρόγραμμα περιήγησης ιστού του χρήστη.

Για εγκατάσταση κόμβου:

//nodejs.org/en/download/

Ακόμα κι αν ο κόμβος είναι μονόκλωνο, είναι ακόμα πιο γρήγορο να χρησιμοποιείτε ασύγχρονες λειτουργίες. Για παράδειγμα, ο κόμβος μπορεί να επεξεργαστεί άλλα πράγματα ενώ ένα αρχείο διαβάζεται από το δίσκο ή ενώ περιμένει να ολοκληρωθεί ένα αίτημα HTTP. Η ασύγχρονη συμπεριφορά μπορεί να εφαρμοστεί χρησιμοποιώντας επιστροφές κλήσεων. Επίσης, το JavaScript λειτουργεί καλά με βάσεις δεδομένων JSON και No-SQL.

Ενότητες NPM

Το Nodejs επιτρέπει την ενσωμάτωση των ενοτήτων βιβλιοθηκών στην εφαρμογή. Αυτές οι ενότητες μπορούν να είναι καθορισμένες από τον χρήστη ή ενότητες τρίτων.

Οι λειτουργικές μονάδες τρίτων μπορούν να εγκατασταθούν χρησιμοποιώντας την ακόλουθη εντολή:

npm install module_name

και οι εγκατεστημένες μονάδες μπορούν να χρησιμοποιηθούν χρησιμοποιώντας τη συνάρτηση () :

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” }

Next we will create a server.js file.

In this file we need to require Express and create a reference to a variable from an instance of Express. Static contents like HTML, CSS or JavaScript can be served using express.js:

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

and we can start listening to a port using the code:

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

Now we need to create an HTML file index.html that displays our UI. I have added bootstrap and JQuery cdn.

//index.html    
    

Send Message

Send

Please note that the empty <;/script>tag will be the place where we will write the client side JavaScript code.

In-order to tell Express that, we will be using a static file. We will add a new line inside server.js:

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

We can run the server.js using the command

node ./server.js

or a package called nodemon, so that the changes made in the code will be automatically detected. We will download nodemon using the command

npm install -g nodemon

-g — global, so that it is accessible in all projects.

We will run the code using the command

nodemon ./server.js

If you go to localhost:3000 we can see the index file:

Now that our server is up and running, we need to create our database. For this app we will having a No-SQL database and will be using Mongodb. I am setting up my mongodb in mlab.com. Our database will contain a single collection called messages with fields name and message.

In-order to connect this database to the app, we will use another package called Mongoose.

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); }) })

Και στην ετικέτα σεναρίου πλευράς πελάτη στο index.html, προσθέστε τον ακόλουθο κώδικα:

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

Έτσι κάθε φορά που δημοσιεύεται ένα μήνυμα, ο διακομιστής θα ενημερώνει τα μηνύματα στο div μήνυμα.

Μεγάλος!!

Αυτή είναι μια πολύ βασική εφαρμογή που μπορούμε να δημιουργήσουμε στο Node.js. Υπάρχουν πολλά περιθώρια βελτίωσης. Ο τελικός κωδικός βρίσκεται στη διεύθυνση //github.com/amkurian/simple-chat

διακομιστής.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); });

Ελπίζω ότι αυτό ήταν χρήσιμο στην κατανόηση ορισμένων βασικών εννοιών.

Μερικοί χρήσιμοι σύνδεσμοι

Socket.IO

Το SOCKET.IO 2.0 ΕΙΝΑΙ ΕΝΔΕΧΕΤΑΙ ΜΕ ΤΟ ΓΡΗΓΟΡΟ ΚΑΙ ΠΙΟ ΑΞΙΟΠΙΣΤΟ ΑΚΙΝΗΤΟ ΠΡΑΓΜΑΤΙΚΟΥ ΧΡΟΝΟΥ ~ / Projects / tweets / index.js var io =… socket.io Express - Node.js web application framework

Το Express είναι ένα ελάχιστο και ευέλικτο πλαίσιο εφαρμογής διαδικτύου Node.js που παρέχει ένα ισχυρό σύνολο δυνατοτήτων για το web και… expressjs.com

//mongoosejs.com/