IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

nothus

Sockets : de IO à l'interprocessus grâce XML-RPC (NodeJS / Python)

Noter ce billet
par , 24/07/2016 à 18h24 (1177 Affichages)
Bonjour chers lecteurs,

M'étant bien pris la tête pour des bricoles et à des fins d'aide-mémoire, ci-joint un code fonctionnel (testé sous VirtualBox + Ubuntu 14.04.3)...

Objectif : récupérer les requêtes d'un utilisateur Web pour les faire transiter vers un script Python (3) - notamment pour former une API qui puisse indifféremment utilisé l'un ou l'autre des processus - en fonction de nos besoins.

Méthode utilisée : NodeJS gère la partie client Web (HTTP et SocketIO). Il s'interface avec un script Python lancé grâce à child_process.spawn puis les deux dialoguent grâce aux requêtes XML-RPC. Attention le code présenté ne fournit aucune sécurité.

---

MàJ du 27/07/2016 - Méthode "brutale" pour la création de la requête par SocketIO

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var elements = { 
	"methodName": "exemple", 
	"params": [ 
		1, 
		2
	] 
}; 

function XMLRPC(Elements) { 
	
	Elements["methodName"] = Elements["methodName"] || ""; 
	Elements["params"] = Elements["params"] || []; 
	Elements["params"] = Array.isArray(Elements["params"])?Elements["params"]:[]; 
	var params = ""; 
	for(var i=0; i<Elements["params"].length; i++) { 
		switch(typeof(Elements["params"][i])) { 
			default: 
				var type = "string"; 
				var valeur = String(Elements["params"][i]); 
				break; 
			case "boolean": 
				var type = "boolean"; 
				var valeur = Elements["params"][i]?"1":"0"; 
				break; 
			case "number": 
				var type = "int"; 
				var valeur = String(Elements["params"][i]); 
				break; 
		} 
		params += `<value><${type}>${valeur}</${type}></value>`;
	} 
	return `<methodCall>
		<methodName>${Elements['methodName']}</methodName>
		<params> 
			${params}
		</params>
	</methodCall>`; 
	
}; 

 XMLRPC(elements);

Le résultat sera :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
<methodCall>
<methodName>exemple</methodName>
<params>
<value><int>1</int></value><value><int>2</int></value>
</params>
</methodCall>
---

MàJ du 27/07/2016 (2) - Méthode par le DOM pour la création de la requête par SocketIO

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
var elements = { 
	"methodName": "exemple", 
	"params": [ 
		1, 
		2 
	] 
}; 

function XMLRPC(Elements) { 
	if (typeof(Elements)!="object") 
		return false; 
	if ("methodName" in Elements==false) 
		return false; 
	if ("params" in Elements==false) 
		return false; 
	if (Array.isArray(Elements["params"])==false) 
		return false; 
	var docXML = document.implementation.createDocument (null,"methodCall"); 
	docXML.documentElement.appendChild(docXML.createElement("methodName").appendChild(document.createTextNode(String(Elements["methodName"])))); 
	var params = doc.createElement("params"); 
	for(var i=0; i<Elements["params"].length; i++) { 
		switch(typeof(Elements["params"][i])) { 
			default: 
				var type = "string"; 
				var valeur = String(Elements["params"][i]); 
				break; 
			case "boolean": 
				var type = "boolean"; 
				var valeur = Elements["params"][i]?"1":"0"; 
				break; 
			case "number": 
				var type = "int"; 
				var valeur = String(Elements["params"][i]); 
				break; 
		} 
		
		var e_tmp = docXML.createElement(type)
		e_tmp.appendChild(document.createTextNode(valeur)); 
		params.appendChild(e_tmp);
	} 
	docXML.documentElement.appendChild(params); 
	return docXML; 
} 

XMLRPC(elements);
---

Repérer un processus Python 3 qui se balade tout seul...

ps -AH | grep python3

---

Fichier NodeJS...

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var xmlrpc = require('xmlrpc'); 

const spawn = require('child_process').spawn;
const Pythonique = spawn('python3', ['/home/julien/xmlrpc-test.py']); 

Pythonique.on("close", (code) => { 
  console.log("Le processus Python s'est arrêté avec le code : ${code}");
}); 

var ClientXMLRPC = xmlrpc.createClient({ host: "127.0.0.1", port: 9090, path: "/xmlrpc"}); // le path peut servir à différencier plusieurs API pour un même script Python lancé (par exemple) 

var http = require("http");

var Serveur = http.createServer(function(req, res) {
	res.writeHead(200, {"Content-Type": "text/html"}); 
	res.end('<!DOCTYPE html><html><head><meta charset="utf-8" /><title>Socket interprocessus NodeJS-Python vers le web grâce à Socket.io</title></head><body><script src="/socket.io/socket.io.js"></script><script>var socket = io.connect(\'http://192.168.0.24:8080\'); socket.on("aff",function(M) { document.getElementsByTagName("p")[0].innerHTML = M; });</script><p>Ce message est d\'origine.</p></body></html>'); 
}); 

var io = require("socket.io").listen(Serveur);

io.sockets.on("connection", function (socket) { 
	
	ClientXMLRPC.methodCall('MultiplieToi', [5,5], function (Erreur, Retour) { 
		if (Erreur!=null) { 
			
			socket.emit("aff","Une erreur ! "+Erreur); 
			
		} else { 
			
			socket.emit("aff","Cinq fois cinq = "+Retour); 
			
		} 
	}); 
	
});

Serveur.listen(8080);
---

Fichier Python3...

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python3

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler

class IntercepteurRequete(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/xmlrpc',)

ServeurXMLRPC = SimpleXMLRPCServer( 
    ("", 9090),
    requestHandler=IntercepteurRequete
)
ServeurXMLRPC.register_introspection_functions()

def Multiplication(x,y):
    return x * y

ServeurXMLRPC.register_function(Multiplication, 'MultiplieToi')

ServeurXMLRPC.serve_forever()

Résultat

Une fois le client connecté par son navigateur, ce dernier charge SocketIO et la connection par IO demande à Python de fournir la réponse à une requête (ici une simple multiplication). Sa réponse est renvoyée au navigateur du client toujours pas NodeJS ; puis la réponse est affichée dans la navigateur à la place d'un message d'origine.

---

Bonne soirée !

Envoyer le billet « Sockets : de IO à l'interprocessus grâce XML-RPC (NodeJS / Python) » dans le blog Viadeo Envoyer le billet « Sockets : de IO à l'interprocessus grâce XML-RPC (NodeJS / Python) » dans le blog Twitter Envoyer le billet « Sockets : de IO à l'interprocessus grâce XML-RPC (NodeJS / Python) » dans le blog Google Envoyer le billet « Sockets : de IO à l'interprocessus grâce XML-RPC (NodeJS / Python) » dans le blog Facebook Envoyer le billet « Sockets : de IO à l'interprocessus grâce XML-RPC (NodeJS / Python) » dans le blog Digg Envoyer le billet « Sockets : de IO à l'interprocessus grâce XML-RPC (NodeJS / Python) » dans le blog Delicious Envoyer le billet « Sockets : de IO à l'interprocessus grâce XML-RPC (NodeJS / Python) » dans le blog MySpace Envoyer le billet « Sockets : de IO à l'interprocessus grâce XML-RPC (NodeJS / Python) » dans le blog Yahoo

Mis à jour 27/07/2016 à 14h45 par Nothus

Catégories
Javascript , Développement Web , Programmation , Python

Commentaires