sql >> Database teknologi >  >> NoSQL >> MongoDB

Realtidschat med Modulus og Node.js

I denne vejledning vil jeg vise dig, hvordan du implementerer en chatapplikation i realtid med Node.js, Socket.IO og MongoDB, og derefter vil vi implementere denne applikation til Modulus sammen.

Først og fremmest, lad mig vise dig det endelige udseende af applikationen, som vi vil have i slutningen af ​​artiklen.

Node.js vil være kernen i applikationen med Express som MVC, MongoDB for databasen og Socket.IO til realtidskommunikation. Når vi er færdige, vil vi implementere vores applikation til Modulus. MongoDB-delen findes faktisk inde i Modulus.

1. Scenarie

  1. John vil bruge vores applikation og åbner den i browseren.
  2. På den første side vælger han et kaldenavn, der skal bruges under chat, og logger på for at chatte.
  3. I tekstområdet skriver han noget og trykker på Enter.
  4. Teksten sendes til en RESTful-tjeneste (Express), og denne tekst er skrevet til MongoDB.
  5. Før du skriver i MongoDB, vil den samme tekst blive udsendt til de brugere, der i øjeblikket er logget ind på chat-appen.

Som du kan se, er dette en meget simpel app, men den dækker næsten alt til en webapplikation. Der er intet kanalsystem i denne applikation, men du kan forkaste kildekoden og implementere kanalmodulet til praksis.

2. Projektdesign fra bunden

Jeg vil prøve at forklare de små stykker af projektet først og kombinere dem til sidst. Jeg vil starte fra bagenden til forenden. Så lad os starte med domæneobjekterne (MongoDB-modeller).

2.1. Model

Til databaseabstraktion vil vi bruge Mongoose. I dette projekt har vi kun én model kaldet Message . Denne meddelelsesmodel indeholder kun text , createDate ,  og author . Der er ingen model for forfatteren som User fordi vi ikke fuldt ud implementerer et brugerregistrerings-/loginsystem. Der vil være en simpel kaldenavngivende side, og dette kaldenavn vil blive gemt i en cookie. Dette vil blive brugt i Message model som tekst i author Mark. Du kan se et eksempel på en JSON-model nedenfor:

{

    text: "Hi, is there any Full Stack Developer here?"

    author: "john_the_full_stack",

    createDate: "2015.05.15"

}

For at oprette dokumenter som dette, kan du implementere en model ved at bruge Mongoose-funktionerne nedenfor:

var mongoose = require('mongoose')



var Message = new mongoose.Schema({

    author: String,

    message: String,

    createDate: {

        type: Date,

        default: Date.now

    }

});



mongoose.model('Message', Message)

Du skal blot importere Mongoose-modulet, definere din model med dens felter og feltattributter i JSON-format, og oprette en model med navnet Message . Denne model vil blive inkluderet på de sider, du vil bruge.

Måske har du et spørgsmål om, hvorfor vi gemmer beskeden i databasen, når vi allerede udsender denne besked til brugeren i samme kanal. Det er rigtigt, at du ikke behøver at gemme chatbeskeder, men jeg ville bare forklare databaseintegrationslaget. I hvert fald vil vi bruge denne model i vores projekt inde i controllerne. Controllere?

2.2. Controller

Som jeg sagde tidligere, vil vi bruge Express til MVC-delen. Og C   her står for Controller . For vores projekter vil der kun være to endepunkter for meddelelser. En af dem er til at indlæse nylige chatbeskeder, og den anden er til håndtering af sendte chatbeskeder til at gemme i databasen og derefter udsende til kanalen.

.....

app.get('/chat', function(req, res){

    res.sendFile(__dirname + '/index.html');

});



app.get('/login', function(req, res){

    res.sendFile(__dirname + '/login.html');

});



app.post('/messages', function(req, res, next) {

    var message = req.body.message;

    var author = req.body.author;

    var messageModel = new Message();

    messageModel.author = author;

    messageModel.message = message;

    messageModel.save(function (err, result) {

       if (!err) {

           Message.find({}).sort('-createDate').limit(5).exec(function(err, messages) {

               io.emit("message", messages);

           });

           res.send("Message Sent!");

       } else {

           res.send("Technical error occurred!");

       }

    });

});



app.get('/messages', function(req, res, next) {

    Message.find({}).sort('-createDate').limit(5).exec(function(err, messages) {

        res.json(messages);

    });

});

.....

Den første og anden controller er kun til at betjene statiske HTML-filer til chat- og login-siderne. Den tredje er til håndtering af postanmodningen til /messages   slutpunkt for oprettelse af nye beskeder. I denne controller konverteres først anmodningsteksten til meddelelsesmodellen, og derefter gemmes denne model i databasen ved at bruge Mongoose-funktionen save . 

Jeg vil ikke dykke så meget ned i Mongoose - du kan se dokumentationen for yderligere detaljer. Du kan give en tilbagekaldsfunktion til gemmefunktionen for at kontrollere, om der er et problem eller ej. Hvis det lykkes, har vi hentet de sidste fem poster sorteret i faldende rækkefølge efter createDate , og har udsendt fem beskeder til kunderne i kanalen.

Ok, vi er færdige med MC .  Lad os skifte til View del.

2.3. Vis

Generelt kan en skabelonmotor som Jade, EJS, Styr osv. bruges i Express. Vi har dog kun én side, og det er en chatbesked, så jeg vil servere denne statisk. Faktisk, som jeg sagde ovenfor, er der yderligere to controllere til at betjene denne statiske HTML-side. Du kan se følgende for visning af en statisk HTML-side.

app.get('/chat', function(req, res){

    res.sendFile(__dirname + '/index.html');

});



app.get('/login', function(req, res){

    res.sendFile(__dirname + '/login.html');

});

Dette slutpunkt tjener blot index.html og login.html ved at bruge res.sendFile . Begge  index.html og login.html er i samme mappe som server.js, hvorfor vi brugte __dirname før HTML-filnavnet.

2.4. Frontend

På forsiden har jeg brugt Bootstrap, og der er ingen grund til at forklare, hvordan jeg formåede at gøre det. Jeg har simpelthen bundet en funktion til et tekstfelt, og hver gang du trykker på Enter  tasten eller Send  knappen, vil beskeden blive sendt til back-end-tjenesten.

Denne side har også en påkrævet js-fil af Socket.IO for at lytte til kanalen kaldet message . Socket.IO-modulet er allerede importeret i bagenden, og når du bruger dette modul på serversiden, tilføjer det automatisk et slutpunkt til betjening af Socket.IO js-filen, men vi bruger det, der serveres fra cdn <script src="//cdn.socket.io/socket.io-1.3.5.js"></script> . Når der kommer en ny besked til denne kanal, vil den automatisk blive registreret, og beskedlisten vil blive opdateret med de sidste fem beskeder.

<script>

        var socket = io();

        socket.on("message", function (messages) {

            refreshMessages(messages);

        });



        function refreshMessages(messages) {

            $(".media-list").html("");

            $.each(messages.reverse(), function(i, message) {

                $(".media-list").append('<li class="media"><div class="media-body"><div class="media"><div class="media-body">'

                + message.message + '<br/><small class="text-muted">' + message.author + ' | ' + message.createDate + '</small><hr/></div></div></div></li>');

            });

        }



        $(function(){



            if (typeof $.cookie("realtime-chat-nickname") === 'undefined') {

                window.location = "/login"

            } else {

                $.get("/messages", function (messages) {

                    refreshMessages(messages)

                });



                $("#sendMessage").on("click", function() {

                    sendMessage()

                });



                $('#messageText').keyup(function(e){

                    if(e.keyCode == 13)

                    {

                        sendMessage();

                    }

                });

            }



            function sendMessage() {

                $container = $('.media-list');

                $container[0].scrollTop = $container[0].scrollHeight;

                var message = $("#messageText").val();

                var author = $.cookie("realtime-chat-nickname");

                $.post( "/messages", {message: message, author: author}, function( data ) {

                    $("#messageText").val("")

                });

                $container.animate({ scrollTop: $container[0].scrollHeight }, "slow");

            }

        })

    </script>

Der er endnu et tjek i ovenstående kode:cookie-delen. Hvis du ikke har valgt noget kaldenavn til chat, betyder det, at cookien ikke er indstillet til kaldenavnet, og du vil automatisk blive omdirigeret til login-siden.

Hvis ikke, vil de sidste fem beskeder blive hentet ved et simpelt Ajax-opkald til /messages endepunkt. På samme måde, når du klikker på Send eller tryk på Enter tast, vil tekstbeskeden blive hentet fra tekstboksen, og kaldenavnet hentes fra cookien, og disse værdier vil blive sendt til serveren med en postanmodning. Der er ingen streng kontrol af kaldenavnet her, fordi jeg ønskede at fokusere på realtidsdelen, ikke brugergodkendelsesdelen.

Som du kan se, er den overordnede struktur af projektet meget enkel. Lad os komme til implementeringsdelen. Som jeg sagde tidligere, vil vi bruge Modulus, en af ​​de bedste PaaS til at implementere, skalere og overvåge din applikation på det sprog, du vælger.

3. Implementering

3.1. Forudsætninger

Den første ting, der falder mig ind, er at vise dig, hvordan du implementerer, men for en vellykket implementering har vi brug for en fungerende database. Lad os se på, hvordan man opretter en database på Modulus og derefter udfører implementeringen.

Gå til Modulus-dashboardet efter oprettelse af en konto. Klik på Databaser  menuen til venstre, og klik på Opret database.

Udfyld de påkrævede felter i pop op-formularen som nedenfor.

Når du udfylder de påkrævede felter og klikker på Opret,  det vil oprette en MongoDB-database til dig, og du vil se din database-URL på skærmen. Vi vil bruge MONGO URI ,  så kopier den URI.

I vores projekt hentes Mongo URI fra miljøvariablen MONGO_URI , og du skal indstille den miljøvariabel i dashboardet. Gå til betjeningspanelet, klik på Projekter menuen, vælg dit projekt på listen, og klik på Administration i venstre menu. På denne side vil du se afsnittet med miljøvariabler, når du ruller ned på siden, som vist nedenfor.

Du kan implementere til Modulus på to måder: 

  • upload af projektets ZIP-fil ved at bruge dashboardet
  • implementering fra kommandolinjen ved hjælp af Modulus CLI

Jeg vil fortsætte med kommandolinjeindstillingen, fordi den anden er nem at gøre. Først og fremmest skal du installere Modulus CLI:

npm install -g modulus

Gå til din projektmappe og udfør følgende kommando for at logge på Modulus.

modulus login

Når du udfører kommandoen ovenfor, bliver du bedt om at indtaste et brugernavn og en adgangskode:

Hvis du har oprettet en konto ved at bruge GitHub, kan du bruge --github mulighed.

modulus login --github

Nu er du logget ind på Modulus, og det er tid til at oprette et projekt. Brug følgende kommando til at oprette et projekt:

modulus project create "Realtime Chat"

Når du kører denne funktion, bliver du bedt om køretiden. Vælg den første mulighed, som er Node.js, og for det andet bliver du bedt om servostørrelsen, og du kan beholde den som standard.

Vi har lavet et projekt, og denne gang vil vi implementere vores nuværende projekt til Modulus. Udfør følgende kommando for at sende det aktuelle projekt til Realtime Chat projekt på Modulus-siden.

modulus deploy

Det vil implementere dit projekt, og du vil få din kørende projekt-URL i slutningen af ​​meddelelsen om succesfuld implementering:

Realtime Chat running at realtime-chat-46792.onmodulus.net

Som du kan se, er implementeringen til Modulus meget let!

Modulus CLI har meget nyttige kommandoer til brug under dit projektimplementering eller under kørsel. For at følge logfiler for dit igangværende projekt kan du f.eks. bruge modulus project logs tail , for at oprette en MongoDB-database, brug modulus mongo create <db-name> , for at indstille en miljøvariabel brug modulus env set <key> <value> , osv. Du kan se en komplet liste over kommandoer ved at bruge Modulus-hjælp.


  1. Brug MongoEngine og PyMongo sammen

  2. Rækkefølgen af ​​svar på MongoDB $i forespørgsel?

  3. Kan ikke oprette forbindelse til redis-server fra docker-container

  4. Hvordan aktiverer man godkendelse på MongoDB gennem Docker?