par , 24/07/2016 à 18h24 (1198 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
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 :
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
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...
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...
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 !