3. WAMP.ws
est un protocole créé pour tirer parti des
websockets
(http://wamp.ws/)
Il permet de faire communiquer en temps réel
des technologies différentes ainsi que des
processus et machines différentes.
4. WAMP.ws offre deux outils
RPC
PUB/SUB
Depuis et vers :
● JS (Node et Navigateur)
● Python (pur)
● C++
● Java
● Objective-C
● PHP
● C#
&
5. RPC : Remote Procedure Call
● Permet d'appeler une fonction d'un autre code à
distance à travers une websocket.
● Asynchrone, performant, propre, léger. Mais simple.
● Paramètres et valeurs de retour peuvent être :
arrays, maps, nombres et chaînes.
● Marche entre deux langages différents.
● Marche entre processus locaux ou à travers
internet.
6. RPC – Exemple 1
Tout ce qu'on fait d'habitude avec AJAX
Navigateur
Comme un GET /user/profile, mais plus rapide puisque via Websocket.
Serveur
getUserProfile()
{'user' : 'sam', 'id' : 1}
RPC
7. RPC – Exemple 2
Communication entre navigateurs
Navigateur
de Sam
Si on code un jeu d'échecs et que je bouge un pion, mon navigateur peut dire
directement à celui de Max de bouger le pion sur son écran.
moveQueen('A', '5')
RPC
Navigateur
de Max
8. RPC – Exemple 3
Push de données vers le navigateur
Si on code un jeu d'échecs avec une intelligence artificielle et que c'est au tour du bot,
il peut directement dire au navigateur du joueur humain de bouger le pion sur son écran.
moveQueen('A', '5')
RPC
NavigateurServeur
9. RPC – Exemple 4
Microservices
Plutôt que d'avoir une grosse application centrale qui fait tout, on peut avoir plusieurs processus
séparés qui font chacun une tâche. Avantage : on peut les réutiliser, les partager entre
projets, les redémarrer indépendamment, les répartir sur plusieurs serveurs...
moveQueen('A', '5')
RPC
Navigateur
Auth IA ChatCompétition
SendMsg('yolo')getPool()login()
10. RPC – Exemple 5
Y a pas que le navigateur dans la vie
Différents services peuvent communiquer entre eux par le même biais. Même protocole, même
API, quels que soient les langages dans lesquels ils sont écrits. Qu'ils soient sur le même serveur
ou non. On peut ainsi déléguer des tâches sur d'autres services, ou machines.
RPC
Python
Rasberry Pi
NodeJSArduino
getVideo()
toggleLED()
11. Montrez-moi le code !
Voici un exemple simple d'un navigateur appelant
une fonction définie dans un autre navigateur.
13. index.html
<!DOCTYPE html><html> <head>
<script
src="https://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.
min.jgz"
type="text/javascript"></script>
</head><body>
<p id="baby">Appelez callMeMaybe() depuis un autre
navigateur :)</p>
</body><script>
// Connexion au serveur de test WAMP.
var connection = new autobahn.Connection({
url: 'wss://demo.crossbar.io/ws',
realm: 'realm1'
});
// Lancer ce code une fois que la connexion est réussie.
connection.onopen = function (session) {
// On déclare que cette fonction est appelable
// par un autre client
session.register('callMeMaybe', function(message){
// On change le contenu de la page.
document.getElementById('baby').innerHTML = message
// On retourne la userAgent du navigateur comme ça vous pouvez
// tester sur 2 nav différents et voir qu'ils communiquent
return navigator.userAgent;
});
};
// Ouvrir la connexion.
connection.open();
</script></html>
14. button.html
<!DOCTYPE html><html> <head>
<script
src="https://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.
min.jgz"
type="text/javascript"></script>
</head><body>
<p><button onClick='callIt()'>Call It, bobby !</button></p>
</body><script>
// Connexion au serveur de test WAMP.
var connection = new autobahn.Connection({
url: 'wss://demo.crossbar.io/ws',
realm: 'realm1'
});
// Lancer ce code une fois que la connexion est réussie.
connection.onopen = function(session) {
callIt = function(){
/* Appel de la fonction callMeMaybe() sur l'autre nav */
session.call("callMeMaybe", ['I called baby !'])
/* L'appel retourne une promesse */
.then(function(userAgent){
alert(userAgent);
});
return false;
}
};
// Ouvrir la connexion.
connection.open();
</script></html>
15. Comment ça marche ?
● Chaque code utilisant WAMP.ws est un client qui a
besoin d'une bibliothèque dédiée à cela.
● Il faut un serveur central, entre tous les clients.
Comme avec RabbitMQ pour AMQP. Ce n'est pas
du P2P à la WebRTC.
● Les libs et le serveur sont libres, à disposition, prêts
à l'usage.
● Il existe des moyens de sécurisation (permissions,
chiffrement). Ceci est une démo simple.
16. RPC – Sous le capot
Communication entre navigateurs
Navigateur
de Sam
Même si on ne le voit pas en codant, il y a un routeur qui transmet les messages.
Il faut ce routeur installé quelque part pour que WAMP fonctionne.
Navigateur
de Max
moveQueen('A', '5')
Routeur
17. RPC – Sous le capot
Communication entre navigateurs
AutoBahnJS
moveQueen('A', '5')
AutoBahnJSCrossbar.io
AutobahnX (AutobahnPython, AutobahnJS, AutobanCpp…) sont les noms des libs
les plus utilisées pour permettre à votre code, le client, de parler WAMP.
Crossbar.io est le nom du routeur le plus complet.
18. Pour vous
● Vous allez uniquement coder le client, avec une
des bibliothèques Autobahn.
● Pour vos tests vous pouvez utiliser le routeur
de démonstration (wss://demo.crossbar.io/ws).
Il n'y a rien à installer.
● En production, vous installez crossbar.io. Un
peu comme on installe Apache ou Nginx pour
faire du HTTP.
19. PUB/SUB
● Un client s'abonne (SUBscribe) à un sujet.
● Un autre client publie un message (PUBlish) sur ce
sujet.
● Tous les clients abonnés à ce sujet en particulier
reçoivent le message.
20. PUB/SUB
● Un client s'abonne (SUBscribe) à un sujet.
● Un autre client publie un message (PUBlish) sur ce
sujet.
● Tous les clients abonnés à ce sujet en particulier
reçoivent le message.
Même principe que RPC, mais permet d'envoyer un
messages à 0 ou N clients, pas juste 1. Néanmoins, il
n'y a pas de valeur de retour possible.
21. PUB/SUB – Exemple 1
Notifications
Navigateur
Le serveur vient de mettre à disposition une nouvelle vidéo. Tous les
navigateurs reçoivent immédiatement l'information et l'affichent sur la page.
Serveur
{'title: 'Chat rigolo', 'id' : 2}
SUB : abonnés au sujet « nouvelle vidéo »
Navigateur Navigateur
PUB
22. PUB/SUB – Exemple 2
Synchronisation
Web
Crawler
Tous vos composants sont toujours au courant de tout ce qu'ils
doivent savoir, où qu'ils soient. Ici, si l'admin change la valeur d'un
paramètre, il peut prévenir tous les processus concernés.
Serveur
d'encodage
Site Web
SUB : abonnés au sujet « changement
d'un paramètre »
Admin
{'settings': 'debug',
'oldValue' : false,
'newValue' : true}
23. Montrez-moi le code !
Même exemple que pour RPC, mais cette fois, on
peut ouvrir index.html dans plusieurs tabs à la
fois.
25. index.html
<!DOCTYPE html><html> <head>
<script
src="https://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.
min.jgz"
type="text/javascript"></script>
</head><body>
<p id="baby">J'attends des nouvelles de fascinatingSubject</p>
</body><script>
// Connexion au serveur de test WAMP.
var connection = new autobahn.Connection({
url: 'wss://demo.crossbar.io/ws',
realm: 'realm1'
});
// Lancer ce code une fois que la connexion est réussie.
connection.onopen = function (session) {
// On déclare que cette fonction est appelée si il y a des
nouvelles
// à propos de ce sujet
session.subscribe('fascinatingSubject', function(message){
// On change le contenu de la page.
document.getElementById('baby').innerHTML = message
// Pas de valeur de retour, le PUB/SUB est à sens unique
});
};
// Ouvrir la connexion.
connection.open();
</script></html>
26. button.html
<!DOCTYPE html><html> <head>
<script
src="https://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.
min.jgz"
type="text/javascript"></script>
</head><body>
<p><button onClick='sayIt()'>Say It, bobby !</button></p>
</body><script>
// Connexion au serveur de test WAMP.
var connection = new autobahn.Connection({
url: 'wss://demo.crossbar.io/ws',
realm: 'realm1'
});
// Lancer ce code une fois que la connexion est réussie.
connection.onopen = function(session) {
sayIt = function(){
/* Publication sur le sujet fascinatingSubject */
session.publish("fascinatingSubject", ['Amazing !']);
// Pas de retour de valeur puisqu'on ne sait pas quels
// clients vont recevoir le message
}
};
// Ouvrir la connexion.
connection.open();
</script></html>
28. Que faire de tout ça ?
● Des apps Web complètes. WAMP est un bon compagnon
de frameworks comme AngularJS et remplace AJAX ou les
websockets à la main pour une mise à jour en temps réel.
● Des grappes d'objets connectés (IoT, Rasberry PI,
Arduino…) : remplace MQTT.
● Des microservices : authentification, logging, encodage
video. Remplace AMQP et ZeroMQ.
● Des jeux vidéos.
● Des applications collaboratives (à la Google Doc).
● Des apps Androids ou iOS natives.
29. A propos de crossbar.io
● Crossbar est un routeur WAMP complet. Sans
routeur, les clients ne peuvent se parler.
● Il doit être accessible via websocket.
● Il peut gérer le cycle de vie des clients.
● Il peut aussi gérer le cycle de vie de processus non
WAMP : c'est un gestionnaire de processus complet
(comme supervisord) afin de faciliter les
architectures à base de plusieurs micro-services.
● Il intègre même un serveur Web si nécessaire.
30. Où est le piège ?
● Technologie encore jeune. WAMP V1 vient d'être
déprécié en faveur de WAMP 2.
● Des outils qui restent à créer : authentification
utilisateur, debugage avancé...
● Obligation d'être asynchrone : pour le moment
incompatible avec WSGI (et donc Django). Un
bridge est en projet.
● Une doc toujours en évolution (mais je viens d'être
embauché pour ça).
31. Does it blend ?
En stressant un peu sa stack WAMP, on peut :
● Envoyer 1,000 PubSub/sec de 32+ bytes vers 1,000 abonnés pour
une latence moyenne de 25 ms avec une charge CPU de 65%.
ou
● Envoyer 6,000 RPC/sec, avec une latence moyenne de 400 ms.
ou
● Servir 6,000 clients, avec une latence moyenne de 850ms.
32. Does it blend ?
En stressant un peu sa stack WAMP, on peut :
● Envoyer 1,000 PubSub/sec de 32+ bytes vers 1,000 abonnés pour
une latence moyenne de 25 ms avec une charge CPU de 65%.
ou
● Envoyer 6,000 RPC/sec, avec une latence moyenne de 400 ms.
ou
● Servir 6,000 clients, avec une latence moyenne de 850ms.
Sur un Rasberry Pi :)
33. Par où commencer ?
Choisissez votre langage, et écrivez un petit client
à l'aide du serveur de démo :
http://crossbar.io/docs/Choose-your-Weapon/