Il y a quelque temps je vous avais laissé avec une introduction ultra basique de nodejs avec l'application qui ne servait à rien si ce n'est à poser quelques bases. Voici la suite

Dans cet exemple, le but sera de faire un chat basique en Ajax. On va modifier les sources du post précédent pour arriver à nos fins

 

Nous avons vu que la base utilisait les templates ejs (pour un cours de rattrapage, c'est par ici, c'est en anglais, mais c'est simple ).

 

Mise en place d’un écran de login basique

Pour un chat, la première chose à faire est s'identifier. On va donc créer un template d'identification tout simple. Celui-ci n'a strictement aucun intérêt, mais c'est plus propre ainsi.

On va donc l'enregistrer dans /views/login.ejs

Il est simplement constitué d'un champ de saisi Username et d'un bouton.

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
  <form method="post" action="/login">
      <h1>Identification Username</h1>
      <input name="username" autofocus>
      <button>OK</button>
    </form>
  </body>
</html>

 

On va également modifier la route de base pour passer par le login.

Dans /routes/index.js on modifie la route de base de la façon suivante

exports.index = function(req, res){

  res.render('login', { title: 'Login' });

};

 

TEST1

Lancez le test depuis le répertoires “messages”  avec la commande suivante:

supervisor app.js

Allez dans votre navigateur et entrez http://localhost:3000 

Si vous avez l’idée d’entrer un prénom et de valider vous allez obtenir une erreur. Ce qui est normal vu que nous n’avons pas géré la route /login !!!

Vous l’aurez compris cet exemple n’a guère plus d’intérêt que la création de la base node.js.

 

Petite amélioration de App.js et templates index.ejs

 

On va ajouter quelques routes, des variables globales (on sait en php faut jamais, jamais faire ça, ça tombe bien on est pas en php).

Modification du App.js - v2

En haut du app.js on ajoute deux variables globales

var Messages = []; // stockage des messages

var Username = ""; // stokage du Username

 

Ensuite on ajoute 2 routes et un peu de traitements pour ajouter les messages dans le tableau global Messages et la variable Username.

/*
Ajout de la route pour login
*/

app.post('/login',function(req,res) {
  Username = req.body.username;
  res.render('index', {
  title : Username, Username:'',sessionID : req.sessionID, Messages:''
  });
});

/*
 Ajout de la route et le traitement des messages
*/

app.post('/envoyer', function(req,res) {
  if (Username !== "" && Username !== undefined) {
    Messages.push({Username:Username,Texte:req.body.message});
    // on dépaque les messages à l'ancienne
    var val="";
    for (var i=0 in Messages) {
      val += "<li>"+Messages[i].Username + ':' + Messages[i].Texte+"</li>";
    }
    // On envoi les messages vers la page index
    res.render('index',{
      title : 'Messages', Username: Username,sessionID : req.sessionID,Messages : val
    });

  }
  // SI on est pas connecté on envoi vers la page de connexion
  else {
     res.redirect('/');
   }
});

 

Modification du template index.ejs - v2

Ici pas grand chose à faire, juste ajouter un formulaire avec un champ de saisie “message”

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %> <%= Username %></p>
    <form id="message" action="envoyer" method="post">
      <label for="message" >Entrez un message></label>
      <input type="text" id="message" name="message"/>
      <button id="buttonsend"> Envoyer </button>
      <ul id="messages">
        <%- Messages %>
      </ul>
    </form>
  </body>
</html> 

 

TEST 2

On lance app.js avec Supervisor si vous l’avez stoppé (ctrl + C)
Sinon Supervisor a du normalement redémarrer app.js. Si pas d’erreur (ce n’est pas lesieur) on doit avoir un truc du style

DEBUG: crashing child
DEBUG: Starting child process with 'node app.js'
Express server listening on port 3000

 

Ce chat ne sert toujours à rien, il faut envoyer un message pour voir les messages des autres !!! et F5 est inhibé.

 

Vous pouvez télécharger l’exemple en cliquant ICI (v2)

NodeJS  img 001

Version avec un peu d’ajax

Pour cette dernière version ultra simple et sans optimisation on va ajouter de l’ajax histoire de ne pas rafraîchir la page mais uniquement les messages.

Modification du template index.ejs - v3

On va transformer un petit peu le template (3 fois rien), un petit bout de javascript. Attention cet exemple ne doit pas fonctionner sous IE (on peut aussi jouer avec Jquery pour simplifier la chose).

On va retirer les balises form et on va ajouter l’ajax

  <script type="text/javascript">
    (function() {
      var httpRequest;
      document.getElementById("buttonsend").onclick = function() { makeRequest('/envoyer'); };

      function makeRequest(url) {
        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
          httpRequest = new XMLHttpRequest();
        } else if (window.ActiveXObject) { // IE
          try {
            httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
          }
          catch (e) {
            try {
              httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e) {}
          }
        }

        if (!httpRequest) {
          alert('Giving up :( Cannot create an XMLHTTP instance');
          return false;
        }
        httpRequest.onreadystatechange = modifListMsg;
        httpRequest.open('POST', url);
        httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        httpRequest.send("message="+document.getElementById("message").value);
      }

      //on envoi le message
      function modifListMsg() {
        if (httpRequest.readyState === 4) {
          if (httpRequest.status === 200) {
           document.getElementById("messages").innerHTML = httpRequest.responseText;
          } else {
            alert('There was a problem with the request.');
          }
        }

 

Modification du App.js - v3

Dans App.js, on va ajouter une fonction pour récupérer uniquement le tableau de messages. Cette fonction sera appelé en ajax toutes les 3 secondes

 

On va modifier la fonction de d’ajout dans le tableau en ajoutant un contrôle pour éviter les messages vides.

On va également ajouter une route pour récupérer uniquement le tableau de messages.

app.post('/envoyer', function(req,res) {
  if (Username !== "" && Username !== undefined) {
    if (req.body.message !== undefined && req.body.message !== '') {
      Messages.push({Username:Username,Texte:req.body.message});
    } else {
      sendMessages(res);
    }
  }
  // SI on est pas connecté on envoi vers la page de connexion
  else {
     res.redirect('/');
  }
});

//appel pour l'affichage des messages
app.post('/messages', function (req,res) {
  sendMessages(res);
}); 


//----

// envoi des messages en réponse à un appel
function sendMessages(res) {
  var val="";
  for (var i=0 in Messages) {
    val += "<li>"+Messages[i].Username + ':' + Messages[i].Texte+"</li>";
  }
  // On envoi les messages vers la page index
  res.send(val);
} 

 

 

TEST3

Le système semble parfaitement fonctionner. Il existe un bug qui fait que de temps en autre le dernier message envoyé, est à nouveau envoyé … Je n’ai pas recherché la cause de phénomène étrange.

Vous pouvez télécharger le code tout moisi ici (v3)

NodeJS  img 002 NodeJS  img 003

Conclusion

 

Nous avons un chat basique fonctionnel qui nous à couté quasi aucun effort (on aurait pu faire exactement la même chose tout aussi facilement en PHP). Il  n’est absolument pas optimisé. Toutes les 3 secondes un navigateur est susceptible d’appeler le serveur et chose encore plus drôle lorsque les sessions expirent les messages s’effacent (normal).
Autre soucis les messages sont stockés dans un tableau, si le serveur tombe, tous les messages sont perdus. De plus cela risque d’utiliser beaucoup de mémoire à la longue. On ne connaît pas non plus la date et l’heure du post du message. SI on fait F5 on renvoi le dernier message. Bref ce n’est pas top, il s’agit d’un cas d’étude.

 D’autre part le code pourrait connaitre de nombreuses optimisations. La mise en module par exemple pourrait en être une. L’optimisation de l’écriture du code lui même avec l’utilisation objet des fonctions etc…

 

L’avantage de l’avoir réaliser avec NodeJS est sa grande réactivité et vitesse.

 

Dans un prochain POST on va ajouter une base de donnée pour ne plus perdre les messages. On va utiliser les sockets plutôt un petit ajax, on va horodaté les messages.

 

 

 

 


Vous avez aimé cet article ? Alors partagez-le avec vos amis en cliquant sur les boutons ci-dessous :


Commentaires

  • Aucun commentaire trouvé

Poster un commentaire en tant qu'invité

0

Publicité

 

Communiquez avec Geekmps Sur Facebook

Invité - BENSI Francois
Bonjour merci pour ce post, tout fonctonne très bien à part un détail. Comment modifie t'on une cam...
Test de la Caméra de surveilla... dans Article de Joomla
Merci pour ces mots!
Le chateau des aventuriers en ... dans Article de Joomla
Bonsoir, pour le nombre de barres, avec votre téléphone qui reconnait toutes les fréquences français...
Choisir son téléphone en fonct... dans Article de Joomla
Invité - Damien
Bonjour, j'ai un acer z630, je suis chez red SFR, je capte entre 1 et 3 barres aux alentours de Gren...
Choisir son téléphone en fonct... dans Article de Joomla
Elle est pas mal mais la luminosité semble assez faible sur la photo dans le noir, par contre le des...
Test de la lampe de bureau, po... dans Article de Joomla