Apprentissage de JavaScript côté serveur avec Node.js

Node.js fait actuellement fureur et facilite la création d’applications Web en temps réel hautes performances. Il permet d'utiliser JavaScript de bout en bout, à la fois sur le serveur et sur le client. Ce tutoriel vous guidera à travers l'installation de Node et de votre premier programme "Hello World", pour construire un serveur de streaming Twitter évolutif..

Qu'est-ce que Node.js?



Traditionnellement, JavaScript n’exécutait que le navigateur Web, mais récemment, le projet CommonJS a suscité un intérêt considérable. Jaxer et Narwhal sont d’autres environnements JavaScript côté serveur. Cependant, Node.js est un peu différent de ces solutions car il est basé sur des événements plutôt que sur des threads. Les serveurs Web comme Apache, utilisés pour servir PHP et d'autres scripts CGI, sont basés sur des threads, car ils génèrent un thread système pour chaque requête entrante. Bien que cela convienne à de nombreuses applications, le modèle basé sur les threads ne s'adapte pas correctement à de nombreuses connexions de longue durée comme vous auriez besoin pour servir des applications en temps réel telles que Friendfeed ou Google Wave..

"Chaque opération d'E / S dans Node.js est asynchrone…"

Node.js, utilise une boucle d'événement au lieu de threads et peut évoluer vers des millions de connexions simultanées. Il tire parti du fait que les serveurs passent le plus clair de leur temps à attendre les opérations d’entrées / sorties, telles que la lecture d’un fichier sur un disque dur, l’accès à un service Web externe ou l’attente de la fin du téléchargement du fichier, car ces opérations sont beaucoup plus lentes. que dans les opérations de mémoire. Chaque opération d'E / S dans Node.js est asynchrone, ce qui signifie que le serveur peut continuer à traiter les demandes entrantes pendant que l'opération d'E / S est en cours. JavaScript est extrêmement bien adapté à la programmation par événements car il possède des fonctions et des fermetures anonymes qui rendent la définition des rappels en ligne un jeu d'enfant, et les développeurs JavaScript savent déjà programmer de cette manière. Ce modèle basé sur les événements accélère considérablement la création de Node.js et facilite la mise à l'échelle d'applications en temps réel..


Étape 1 Installation

Node.js fonctionne sur des systèmes Unix, tels que Mac OS X, Linux et FreeBSD. Malheureusement, Windows n’est pas encore pris en charge. Si vous utilisez Windows, vous pouvez l’installer sur Ubuntu Linux à l’aide de Virtualbox. Pour ce faire, suivez ce tutoriel. Vous devrez utiliser le terminal pour installer et exécuter Node.js..

  1. Téléchargez la dernière version de Node.js à partir de nodejs.org (la dernière version en date est 0.1.31) et décompressez-la..
  2. Ouvrez le terminal et lancez les commandes suivantes.
    cd / path / to / nodejs make sudo make install

    Un grand nombre de messages seront envoyés au terminal à mesure que Node.js est compilé et installé..


Étape 2 Bonjour tout le monde!

Chaque nouvelle technologie commence par un "Hello World!" tutoriel, nous allons donc créer un serveur HTTP simple qui sert ce message. Cependant, vous devez d’abord comprendre le système de modules Node.js. Dans Node, la fonctionnalité est encapsulée dans des modules qui doivent être chargés pour pouvoir être utilisés. De nombreux modules sont répertoriés dans la documentation de Node.js. Vous chargez ces modules en utilisant le exiger fonctionne comme ceci:

 var sys = require ("sys");

Cela charge le module sys, qui contient des fonctions permettant de gérer des tâches au niveau du système, telles que l’impression de la sortie sur le terminal. Pour utiliser une fonction dans un module, vous l’appelez dans la variable dans laquelle vous avez stocké le module, dans notre cas. sys.

 sys.puts ("Hello World!");

Exécuter ces deux lignes est aussi simple que d’exécuter le nœud commande avec le nom de fichier du fichier javascript comme argument.

 noeud test.js

Cette sortie "Bonjour le monde!" à la ligne de commande lors de l'exécution.

Pour créer un serveur HTTP, vous devez exiger la http module.

 var sys = require ("sys"), http = require ("http"); http.createServer (fonction (demande, réponse) response.sendHeader (200, "Content-Type": "text / html"); response.write ("Hello World!"); response.close (); ) .listen (8080); sys.puts ("Serveur tournant à l'adresse http: // localhost: 8080 /");

Ce script importe le sys et http modules et crée un serveur HTTP. La fonction anonyme qui est passée dans http.createServer sera appelé chaque fois qu'une requête arrive sur le serveur. Une fois le serveur créé, il est indiqué d'écouter sur le port 8080. Lorsqu'une demande au serveur arrive, nous envoyons d'abord les en-têtes HTTP avec le type de contenu et le code d'état de 200 (avec succès). Ensuite, nous envoyons "Hello World!" et fermez la connexion. Vous remarquerez peut-être que nous devons explicitement fermer la connexion. Cela rendra très facile la transmission de données au client sans fermer la connexion. Si vous exécutez ce script et allez à http: // localhost: 8080 / dans votre navigateur, vous verrez "Hello World!"


Étape 3: un serveur de fichiers statique simple

OK, nous avons donc construit un serveur HTTP, mais il n'envoie rien, sauf "Hello World", quelle que soit l'URL à laquelle vous vous rendez. Tout serveur HTTP doit pouvoir envoyer des fichiers statiques tels que des fichiers HTML, des images et d’autres fichiers. C'est ce que fait le code suivant:

 var sys = require ("sys"), http = require ("http"), url = require ("url"), chemin = require ("chemin"), fs = require ("fs"); http.createServer (fonction (demande, réponse) var uri = url.parse (request.url). nom de chemin; var nomfichier = chemin.join (processus.cwd (), uri); chemin.exist (nomfichier, fonction (existe déjà) ) si (! existe) response.sendHeader (404, "Content-Type": "text / plain"); response.write ("404 Introuvable \ n"); response.close (); return;  fs.readFile (nomfichier, "binaire", fonction (err, fichier) if (err) réponse.sendHeader (500, "Content-Type": "text / plain"); response.write (err + "\ n"); response.close (); return; response.sendHeader (200); response.write (fichier, "binaire"); response.close (););). listen ( 8080); sys.puts ("Serveur tournant à l'adresse http: // localhost: 8080 /");

Nous commençons par exiger tous les modules dont nous aurons besoin dans notre code. Cela inclut le sys, http, url, chemin, et fs ou des modules de système de fichiers. Ensuite, nous créons un serveur HTTP comme nous le faisions auparavant. Cette fois, nous allons utiliser le url module permettant d’analyser l’URL entrante de la demande et de trouver le chemin du fichier en cours d’accès. Nous trouvons le nom de fichier réel sur le disque dur du serveur en utilisant path.join, qui rejoint process.cwd (), ou le répertoire de travail en cours, avec le chemin du fichier demandé. Ensuite, nous vérifions si le fichier existe, ce qui est une opération asynchrone et nécessite donc un rappel. Si le fichier n'existe pas, un message 404 Introuvable est envoyé à l'utilisateur et la fonction est renvoyée. Sinon, nous lisons le fichier en utilisant le fs module en utilisant le codage "binaire" et envoyez le fichier à l'utilisateur. En cas d'erreur de lecture du fichier, nous présentons le message d'erreur à l'utilisateur et fermons la connexion. Comme tout cela est asynchrone, le serveur est capable de répondre à d’autres requêtes tout en lisant le fichier à partir du disque, quelle que soit sa taille..

Si vous exécutez cet exemple et accédez à http: // localhost: 8080 / path / to / file, ce fichier sera affiché dans votre navigateur.


Étape 4: Streamer en temps réel sur Tweet

En nous appuyant sur notre serveur de fichiers statiques, nous allons créer un serveur dans Node.js qui diffuse les tweets vers un client servi via notre serveur de fichiers statiques. Pour commencer, nous aurons besoin d’un module supplémentaire dans cet exemple: le événements module. Le noeud a un concept appelé un EventEmitter, qui est utilisé partout pour gérer les écouteurs d'événements pour les tâches asynchrones. Tout comme dans jQuery ou un autre framework JavaScript côté client dans lequel vous liez des écouteurs d'événements à des clics de souris ou à des requêtes AJAX, Node vous permet de lier des écouteurs d'événements à de nombreuses choses, dont certaines ont déjà été utilisées. Celles-ci incluent toutes les opérations d’entrée / sortie, telles que la lecture d’un fichier, l’écriture d’un fichier, la vérification de l’existence d’un fichier, l’attente de requêtes HTTP, etc. EventEmitter résume la logique de liaison, de suppression de la liaison et de déclenchement de tels écouteurs d'événements. Nous allons utiliser un EventEmitter pour informer les auditeurs lorsque de nouveaux tweets sont chargés. Les premières lignes de notre streameur tweet importent tous les modules requis et définissent une fonction de traitement des fichiers statiques, tirée de notre exemple précédent..

 var sys = require ("sys"), http = require ("http"), url = require ("url"), chemin = require ("chemin"), fs = require ("fs"), événements = require ( "événements"); function load_static_file (uri, réponse) var nomfichier = chemin.join (processus.cwd (), uri); path.exists (nom_fichier, fonction (existe) (! existe) réponse.sendHeader (404, "Type de contenu": "text / plain"); response.write ("404 introuvable \ n") ; response.close (); return; fs.readFile (nomfichier, "binaire", fonction (err, fichier) if (err) reponse.sendHeader (500, "type de contenu": "text / plain" ); response.write (err + "\ n"); response.close (); return; response.sendHeader (200); response.write (fichier, "binaire"); response.close ();) ;); 

Nous avons utilisé le http module pour créer un serveur auparavant, mais il est également possible de créer un client HTTP à l'aide du module. Nous allons créer un client HTTP pour charger les tweets à partir de la chronologie publique de Twitter, effectuée par le get_tweets une fonction.

 var twitter_client = http.createClient (80, "api.twitter.com"); var tweet_emitter = new events.EventEmitter (); function get_tweets () var request = twitter_client.request ("GET", "/1/statuses/public_timeline.json", "hôte": "api.twitter.com"); request.addListener ("response", fonction (response) var body = ""; response.addListener ("data", fonction (data) body + = data;); response.addListener ("end", function ( ) var tweets = JSON.parse (body); if (tweets.length> 0) tweet_emitter.emit ("tweets", tweets););); request.close ();  setInterval (get_tweets, 5000);

Tout d'abord, nous créons un client HTTP sur le port 80 vers api.twitter.com, puis créons un nouveau EventEmitter. le get_tweets function crée une requête HTTP "GET" sur la timeline publique de Twitter et ajoute un écouteur d'événement qui sera déclenché lorsque les serveurs de Twitter répondent. Étant donné que Node.js est asynchrone, les données contenues dans le corps de la réponse sont regroupées en fragments, qui sont captés par le programme d'écoute "data" de la réponse. Cet auditeur ajoute simplement le morceau à la corps variable. Une fois que tous les morceaux sont entrés, le programme d'écoute "fin" est déclenché et nous analysons les données JSON entrantes. Si plus d'un tweet est renvoyé, nous émettre les "tweets" sur notre tweet_emitter, et passez dans le tableau des nouveaux tweets. Cela déclenchera l'écoute de l'événement "tweets" par tous les écouteurs d'événements et enverra les nouveaux tweets à chaque client. Nous retrouvons les nouveaux tweets toutes les cinq secondes en utilisant setInterval.

Enfin, nous devons créer le serveur HTTP pour traiter les demandes.

 http.createServer (fonction (demande, réponse) var uri = url.parse (request.url). nom de chemin; if (uri === "/ stream") var écouteur = tweet_emitter.addListener ("tweets", fonction ( tweets) response.sendHeader (200, "Content-Type": "text / plain"); response.write (JSON.stringify (tweets)); response.close (); clearTimeout (timeout);); var timeout = setTimeout (function () response.sendHeader (200, "Content-Type": "text / plain")); response.write (JSON.stringify ([])); response.close (); tweet_emitter .removeListener (listener);, 10000); else load_static_file (uri, réponse);). listen (8080); sys.puts ("Serveur tournant à l'adresse http: // localhost: 8080 /");

Comme nous l'avons fait avec notre serveur de fichiers statique, nous créons un serveur HTTP qui écoute sur le port 8080. Nous analysons l'URL demandée, et si l'URL est égale à "/courant", nous allons le gérer, sinon nous transmettons la demande à notre serveur de fichiers statiques. Le streaming consiste à créer un auditeur pour écouter de nouveaux tweets sur notre tweet_emitter, qui sera déclenché par notre get_tweets une fonction. Nous créons également un timer pour tuer les requêtes qui durent plus de 10 secondes en leur envoyant un tableau vide. Lorsque de nouveaux tweets entrent, nous les envoyons sous forme de données JSON et désactivons le chronomètre. Vous verrez comment cela fonctionne mieux après avoir vu le code côté client, qui est ci-dessous. Enregistrez-le sous test.html dans le même répertoire que le JavaScript côté serveur.

    Tweet Streamer    

    Ici, nous avons une simple page HTML qui importe la bibliothèque jQuery et définit une liste non ordonnée dans laquelle placer les tweets. Notre code client côté client met en cache la liste des tweets et exécute le load_tweets fonctionner après une seconde. Cela donne au navigateur suffisamment de temps pour terminer le chargement de la page avant de lancer la requête AJAX au serveur. le load_tweets la fonction est très simple: il utilise jQuery getJSON fonction à charger /courant. Lorsqu'une réponse nous parvient, nous parcourons tous les tweets et les ajoutons à la liste de tweets. Ensuite, nous appelons load_tweets encore. Cela crée effectivement une boucle qui charge les nouveaux tweets, qui expire au bout de dix secondes en raison du délai d'attente sur le serveur. Chaque fois qu'il y a de nouveaux tweets, ils sont envoyés au client, qui maintient une connexion continue au serveur. Cette technique s'appelle long-polling.

    Si vous exécutez le serveur en utilisant nœud et allez à http: // localhost: 8080 / test.html, vous verrez le flux chronologique public de Twitter dans votre navigateur.


    Prochaines étapes

    Node.js est une technologie très intéressante qui facilite la création d'applications temps réel hautes performances. J'espère que vous pourrez voir ses avantages et les utiliser dans certaines de vos propres applications. En raison de l'excellent système de modules de Node, il est facile d'utiliser du code pré-écrit dans votre application et de nombreux modules tiers sont disponibles pour à peu près tout, y compris les couches de connexion à la base de données, les moteurs de templates, les clients de messagerie et même des infrastructures complètes reliant tous ces éléments. les choses ensemble. Vous pouvez voir une liste complète des modules sur le wiki Node.js, et d'autres didacticiels sur les nœuds sont disponibles sur How To Node. Je vous recommanderais également de regarder une vidéo de JSConf, dans laquelle Ryan Dahl, le créateur de Node, décrit la philosophie de conception de Node. C'est disponible .

    J'espère que vous avez apprécié ce tutoriel. Si vous avez des commentaires, vous pouvez en laisser un ici ou m'envoyer un message sur Twitter. Heureux acquiesçant!