node.JS
&
Socket.io
par Robin Duval
Socket.io
- Socket.io
- une bibliothèque JavaScript (événementiel)
- pour les applications web en temps réel
- communication bidirectionnelle : client <=> serveur
- Il comporte deux parties:
- une bibliothèque côté client (navigateur),
- une bibliothèque côté serveur pour Node.js
- Les APIs sont quasiment identiques

Socket.io
-
Socket.IO utilise principalement le protocole WebSocket
-
avec un système de polling comme option de repli
-
tout en offrant la même interface
-
-
Socket.IO peut être utilisé
-
comme un simple wrapper WebSocket,
-
broadcasting vers de multiples clients (socket)
-
stockage des données associées à chaque client
-
et gestion des entrés / sorties asynchrones.
-
Node.JS
- Node.js
- est une plateforme logicielle libre et événementielle
- est en JavaScript
- s'oriente vers les applications réseau (+monter en charge).
- utilise la machine virtuelle V8
- implémente sous licence MIT les spécifications CommonJS.

Node.JS
- Node.js
- contient une bibliothèque de serveur HTTP intégrée
- on fait tourner un serveur web
- sans Apache ou Lighttpd
- on contrôle la façon dont le serveur web fonctionne en live
- on fait tourner un serveur web
- est utilisé par
- Groupon, SAP, LinkedIn, Microsoft,
- Yahoo!, Walmart, Rakuten et PayPal.
- contient une bibliothèque de serveur HTTP intégrée
Travaux PRATIQUEs
- Cahier des charges
- avoir un formulaire avec +100 champs
- diffuser
- la mise à jour du formulaire
- l'identifications des personnes (dé)connectées
- l'historique des modifications
TP Côté Client : VIOU
Création de la page htm(euh)l
<!DOCTYPE html>
<html lang="fr">
<body style="width: 100%">
<form style="float:left;width: 55%" action="" id="healthForm"></form>
<div style="margin-left: 55%" id="history">
<form action="" id="loginForm">
<input type="text" name="username" id="username" placeholder="Ton nom" />
</form>
Liste des utilisateurs connectés
<ul id="users"></ul>
Liste des utilisateurs connectés
<ul id="activities"></ul>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="js/client/generateForm.js"></script>
<script type="text/javascript" src="http://192.168.3.240:1337/socket.io/socket.io.js"></script>
<script type="text/javascript" src="js/client/rules.js"></script>
</body>
</html>
TP Côté Client : VIOU
Génération du formulaire (generateForm.js)
(function ($){
for (i = 1; i <= 100; i++) {
$('#healthForm').append('<input style="border-color:yellow;" value="'+ Math.trunc(Math.random()*1000000) +'" type="text" pfd="src int" class="src" id="si' + i + '" />');
$('#healthForm').append('<input style="border-color:grey;" type="text" pfd="dst int" id="da' + i + '" class="text" />');
$('#healthForm').append('<input style="border-color:grey;" type="text" pfd="dst int" id="db' + i + '" class="text" />');
$('#healthForm').append('<input style="border-color:grey;" type="text" pfd="dst int" id="dc' + i + '" class="text" /><br />');
$('#healthForm').append('<input style="border-color:blue;" value="'+ Math.random().toString(36).substring(7) +'" type="text" pfd="src txt" class="src" id="st' + i + '"/>');
$('#healthForm').append('<input style="border-color:grey;" type="text" pfd="dst txt" id="da' + i + '" class="text" />');
$('#healthForm').append('<input style="border-color:grey;" type="text" pfd="dst txt" id="db' + i + '" class="text" />');
$('#healthForm').append('<input style="border-color:grey;" type="text" pfd="dst txt" id="dc' + i + '" class="text" /><br /><br />');
}
})(jQuery);TP : Gestion des Uzeurs
Côté Client
(function ($){
//NOTRE CHAUSSETTE VA SE CONNECTER SUR NOTRE SERVEUR HTTP (NODEJS)
var socket = io.connect('http://192.168.3.240:1337');
var user = "";
$('#loginForm').submit(function (event){
event.preventDefault();
user = $('#username').val();
// NOTRE SOCKET EMET VERS LE SERVEUR HTTP SUR LE CANAL/EVENEMENT LOGIN
socket.emit('login', {
username : $('#username').val()
});
$('#loginForm').hide();
});
// NOTRE SOCKET ATTENDS QUE QQ1 LUI DISE QUOI FAIRE SUR L'EVENEMENT NEWUSER
socket.on('newuser', function(user){
$('#users').append('<li id="'+user.id+'">' + user.id + '</li>');
});
// NOTRE SOCKET ATTENDS QUE QQ1 LUI DISE QUOI FAIRE SUR L'EVENEMENT DISUSER
socket.on('disuser', function(user){
$('#'+user.id).remove();
});
})(jQuery);TP : Gestion des Uzeurs
Côté Serveur
// VARIABLE GLOBALE
var http = require('http');
var io = require('socket.io');
httpServer = http.createServer(function(req, res){
res.end("check this out");
});
//Creation du serveur http avec nodeJs, il écoute sur le 1337
httpServer.listen(1337);
// Notre socket est connecté au serveur http
var io = require('socket.io').listen(httpServer);
var users = {};
// ON SE BRANCHE SUR L'EVENEMENT LIE A UNE CONNEXION / UN SOCKET
// VARIABLE SPECIFIQUE A UN SOCKET / UTILISATEUR
io.sockets.on('connection', function(socket){
var me = false;
for (var k in users){
socket.emit('newuser', users[k]);
}
socket.on('login', function(user){
me = user;
me.id = user.username;
users[me.id] = me;
//ENVOYER UN EVENEMENT DU SERVEUR --> vers le client celle qui est connecté
//socket.emit('newuser');
//ENVOYER UN EVENEMENT DU SERVEUR --> vers les clients qui sont connectés SAUF le user COURANT
//socket.broadcast.emit('newuser');
//ENVOYER UN EVENEMENT DU SERVEUR --> vers les clients qui sont connectés
io.sockets.emit('newuser', me);
});
socket.on('disconnect', function(){
if (!me){
return false;
}
delete users[me.id];
io.sockets.emit('disuser', me);
});
});TP : Gestion dU FORMUL-R
Côté Client
(function ($){
// On récupère l'info du formulaire
$('.src').focusout(function (event){
event.preventDefault();
socket.emit('updateValue', {
id : $(this).attr('id'),
typeNode : $(this).attr('pfd').split(" ")[0],
typeValue : $(this).attr('pfd').split(" ")[1],
value : $(this).val(),
user : user
});
});
// ON AFFICHE L'INFORMATION SUR UN LOG
function log(field) {
$('#activities').prepend('<li id="'+field.id+'">' +
'Le champ #' + field.id +
' a pris la valeur ' + field.value +
'. Le type est ' + field.typeValue +
' par ' + field.user +
'</li>');
}
// ON RECUPERE L'INFORMATION SUR L'EVENEMENT ACTIVITY
socket.on('activity', function(activity){
var color = "red";
if (activity.isValid) {
color = "green";
}
$('#'+activity.id).val(activity.value);
$('#'+activity.id).css("border-color", color);
log(activity);
});
// ON AFFICHE OU NON LE CHAMPS
socket.on('hide', function(id){
$('#activities').prepend('<li style="color:red" id="'+id+'">' +
'Le champ #' + id +
' a été caché </li>');
$('#'+id).hide();
});
socket.on('show', function(id){
$('#activities').prepend('<li style="color:red" id="'+id+'">' +
'Le champ #' + id +
' a été montré </li>');
$('#'+id).show();
});
})(jQuery);TP : Gestion dU FORMUL-R
Côté Serveur
function replaceTag(tag) {
var tagsToReplace = {
'&': '&',
'<': '<',
'>': '>'
};
return tagsToReplace[tag] || tag;
}
function is_int(value){
if((parseFloat(value) == parseInt(value)) && !isNaN(value)){
return true;
} else {
return false;
}
}
function fixTheForm(field){
var rules =
{
"si1":
{
src: "si1",
dest: "da2 db2 dc2",
type: "int",
action: "display"
},
"st2":
{
src: "st2",
dest: "da2 db2 dc2",
type: "txt",
action: "hide"
},
"si3":
{
src: "si3",
dest: "da3 db3 dc3",
type: "int",
action: "display"
},
};
if (typeof rules[field.id] != 'undefined'){
rule = rules[field.id];
field.existRule = true;
field.isValid = true;
if ("int" === rule.type){
field.isValid = is_int(field.value);
}
if ("display" === rule.action){
field.displays = rule.dest.split(" ");
}
if ("hide" === rule["action"]){
field.hides = rule.dest.split(" ");
}
}
return field;
}
// A LA CONNEXION - A L'INTERIEUR
socket.on('updateValue', function(field){
newfield = field;
newfield.existRule = false;
newfield.displays = {};
newfield.hides = {};
newfield.isValid = true;
newfield.value = newfield.value.replace(/[&<>]/g, replaceTag);
fixTheForm(newfield);
for (var k in newfield.hides){
io.sockets.emit('hide', newfield.hides[k]);
}
for (var k in newfield.displays){
io.sockets.emit('show', newfield.displays[k]);
}
io.sockets.emit('activity', newfield);
});VERS L'INFINI ET au delà ! 1/3
-
ExpressJS : framework web minimalist pour node.js
- Pleins d'outils
- pour créer rapidement une API
- pour créer des applications web et mobiles
- couche fine pour couvrir les besoins fondamentaux
- gestion du routing
- générateur d'un squelette
- gestion des erreurs
- possibilité d'utiliser un moteur de template ...
- gestion de la base de données
- Pleins d'outils
VERS L'INFINI ET AU DELÀ ! 2/3
-
Loopback : framework pour créer une API + connexion bdd
- Créez rapidement une API REST de bout en bout.
- Extension pour gérer :
- les pushs,
- gestion de fichiers,
- et la géolocalisation...
- Permet de définir un model de données :
- hasMany, belongsTo, hasAndBelongsToMany
- Automatically generates corresponding relational REST endpoints
- Utilisez StrongLoop Arc pour modifier, déployer et contrôler des applications fait avec Loopback...
VERS L'INFINI ET AU DELÀ ! 3/3
- Apache :
- Cassandra : table avec index et valeur, stockage clé+valeur en colonne
- CouchBD : document JSON
- Google
- LevelDB : stockage clé (ordonné)-valeur de chaîne de caractères
- Neo4j : stockage de graph très performant (payant)
- Redis : gestion de cache, stockage clé+valeur
C'est
terminé !
SocketIO+NodeJS
By Robin Duval
SocketIO+NodeJS
Débuter avec SocketIO+NodeJS
- 405