W drugiej części tworzenia chatu z Node.js i Socket.io użyjemy MongoDB do przechowywania wiadomości napisanych przez użytkowników.

Aby pobrać bazę danych MongoDB przejdź pod ten adres i wybierz odpowiednią dla swojego systemu wersję. Po pobraniu zainstaluj MongoDB. Instalacja jest bardzo prosta i polega głównie na klikaniu Next.

Po zainstalowaniu otwórzmy cmd i przejdźmy do folderu, w którym znajdują się pliki mongod.exe i mongo.exe. W moim przypadku jest to C:\MongoDB\bin. Przejdźmy do tego folderu:

mongo cmd

Możemy teraz uruchomić bazę danych poniższą komendą:

mongod

cmd mongod

Ten widok oznacza, że wszystko działa poprawnie i MongoDB zostało włączone. Otwórzmy kolejne okno cmd (nie zamykamy tego) i przechodzimy do tego samego folderu i wpisujemy komendę:

mongo

cmd mongo

To tutaj zarządzamy naszą bazą danych. MongoDB znacznie różni się od baz danych takich jak mySQL. Przede wszystkim nie definiujemy tutaj tabel i kolumn. Są one automatycznie tworzone gdy otrzymają takie polecenie. Spróbujmy umieścić nowy rekord w tabeli messages wpisując w powyższym oknie cmd:

db.messages.insert( { username: "Devcorner", message: "Hello world." } )

cmd insert mongo

Teraz możemy podejrzeć zawartość tej tabeli wpisując:

db.messages.find()

cmd mongo find

Zauważ, że nie definiowaliśmy wcześniej tabeli oraz kolumn. Wszystko zostało wygenerowane dynamicznie 🙂

Możemy teraz zająć się naszym kodem. Skoro mamy bazę danych, gdzie chcemy przechowywać wszystkie wiadomości to warto byłoby przechowywać również ich autorów. Przejdźmy do pliku index.html i zmodyfikujmy go tak, aby użytkownik musiał podać swoją nazwę przed wysłaniem wiadomości.

Skorzystamy z okna prompt aby użytkownik mógł wpisać swoją nazwę a następnie sprawdzimy czy faktycznie jakąś nazwę wprowadził:

var username = prompt("Nazwa:");

if(username) {

   $('form').submit(function(){
      socket.emit('message', {
         message: $('#msg').val(),
         username: username
      });

      $('#msg').val('');
      return false;
   });

   socket.on('message', function(msg){
      $('#messages').append($('<li>').text(msg.username + ": " + msg.message));
      $("html, body").scrollTop($(document).height());
   });

}

Na początku do zmiennej username przypisujemy nick podany przez użytkownika. Następnie sprawdzamy czy użytkownik cokolwiek wpisał. Jeśli tak to umożliwiamy użytkownikowi wysyłanie i odbieranie wiadomości. Podczas wysyłania wiadomości wysyłamy teraz również nazwę użytkownika.

Podczas odbierania wiadomości wyświetlamy teraz również nazwę użytkownika w formacie Nazwa: Wiadomość.

W nowym oknie cmd przejdźmy teraz do folderu z naszym chatem:

cmd screen 1

Zainstalujmy teraz obsługę MongoDB wpisując:

npm install mongodb

Po instalacji przejdźmy do pliku index.js – naszego serwera. Na samym początku pliku do zmiennej mongo przypiszmy zainstalowany moduł:

var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server),
    mongo = require('mongodb').MongoClient;

Dostosujmy teraz wcześniejszy kod do współpracy z bazą danych:

mongo.connect('mongodb://127.0.0.1/test', function(err, db){
  if(err) throw err;

io.sockets.on('connection', function (socket) {
  console.log("Socket connected.");
  var col = db.collection('messages');

  col.find().toArray(function(err, res){
    if(err) throw err;
    socket.emit('output', res);
  });

  socket.on('message', function(msg){

    var whitespacePattern = /^\s*$/;

    if(whitespacePattern.test(msg.username) || whitespacePattern.test(msg.message)) {
          socket.emit('er', "Wiadomość i nazwa użytkownika nie może być pusta.");
    }

    else {
      col.insert( { username: msg.username, message: msg.message} )
      io.emit('message', {
        message: msg.message,
        username: msg.username
      });
    }

  });

});

});

Na początku przy pomocy mongo.connect łączymy się z bazą test (jest domyślnie tworzona podczas instalacji Mongo). Jeśli wystąpił błąd połączenia to go zwracamy. Następnie łączymy się z Socket.io. Do zmiennej col przypisujemy skrót do naszej tabeli – usprawni to operacje na bazie.

Przy pomocy col.find().toArray pobieramy wszystkie wiadomości i konwertujemy je do tablicy. Tablicę przesyłamy (emit) do klienta (index.html). Podczas odbierania przez serwer wiadomości wysłanej przez użytkownika definiujemy wzór w zmiennej whitespacePattern. Następnie używamy test i sprawdziamy czy nazwa użytkownika lub wiadomość nie składają się wyłącznie z pustych znaków. Jeśli tak to przesyłamy informację o błędzie. W przeciwnym wypadku dodajemy nowy rekord do bazy danych i wysyłamy wiadomość do wszystkich użytkowników.

W ten sposób wiadomości z bazy danych zostaną pobrane tylko raz – przy dołączeniu do chatu. Nowe wiadomości będą pochodziły bezpośrednio z serwera.

Musimy teraz w pliku index.html odebrać wiadomości pobrane z bazy danych. Zaraz za var socket = io(); dodajmy kod:

socket.on('output', function(data){
   if(data.length) {
      for(var x=0; x < data.length; x++){
         $('#messages').append($('<li>').text(data[x].username + ": " + data[x].message));
      }
   }
});

W pliku index.html przed zamykającym znacznikiem </script> dodajmy jeszcze obsługę błędu:

socket.on('er', function(er){
   alert(er);
});

Jeśli pojawił się błąd to wyświetlamy komunikat z serwera. Jest to bardzo prosta walidacja, ale na potrzeby tego przykładu jest wystarczająca.

Możemy teraz uruchomić serwer:

cmd 5

I podejrzeć efekty naszej pracy pod adresem http://localhost:3000.

W kolejnej części przeniesiemy nasz chat z serwera lokalnego do chmury na Heroku.

Paczkę możesz pobrać tutaj.

Bądź pierwszą osobą, która skomentuje ten wpis.