144 votes

Combiner node.js et Python

Node.js correspond parfaitement à notre projet web, mais il y a quelques tâches informatiques pour lesquelles nous préférons Python. Nous avons également déjà un code Python pour ces tâches. Nous sommes très préoccupés par la vitesse, quelle est la manière la plus élégante d'appeler un "worker" Python depuis node.js de manière asynchrone et non bloquante ?

3 votes

Bonjour, pourriez-vous nous dire ce que vous avez choisi et comment cela a fonctionné pour vous ? Il y a des bibliothèques en Python que nous aimons tous utiliser tout en gardant les options de performance et de non-blocage. Merci

0 votes

Pourquoi ne pas simplement créer un processus et communiquer par le biais de l'entrée-sortie du système, comme le suggère cette proposition : sohamkamani.com/blog/2015/08/21/python-nodejs-comm ?

1 votes

Il existe une nouvelle bibliothèque de transition appelée PyNode qui vous permet d'appeler Python et d'obtenir des types JS en retour. La démonstration est faite ici thecodinginterface.com/blog/

125voto

djheru Points 505

Cela ressemble à un scénario dans lequel zeroMQ serait un bon choix. Il s'agit d'un cadre de messagerie similaire à l'utilisation de sockets TCP ou Unix, mais il est beaucoup plus robuste ( http://zguide.zeromq.org/py:all )

Il existe une bibliothèque qui utilise zeroMQ pour fournir un cadre RPC qui fonctionne plutôt bien. Elle s'appelle zeroRPC ( http://zerorpc.dotcloud.com/ ). Voici le bonjour du monde.

Serveur Python "Hello x" :

import zerorpc

class HelloRPC(object):
    '''pass the method a name, it replies "Hello name!"'''
    def hello(self, name):
        return "Hello, {0}!".format(name)

def main():
    s = zerorpc.Server(HelloRPC())
    s.bind("tcp://*:4242")
    s.run()

if __name__ == "__main__" : main()

Et le client node.js :

var zerorpc = require("zerorpc");

var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");
//calls the method on the python object
client.invoke("hello", "World", function(error, reply, streaming) {
    if(error){
        console.log("ERROR: ", error);
    }
    console.log(reply);
});

Ou vice-versa, serveur node.js :

var zerorpc = require("zerorpc");

var server = new zerorpc.Server({
    hello: function(name, reply) {
        reply(null, "Hello, " + name, false);
    }
});

server.bind("tcp://0.0.0.0:4242");

Et le client python

import zerorpc, sys

c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4242")
name = sys.argv[1] if len(sys.argv) > 1 else "dude"
print c.hello(name)

4 votes

Zerorpc peut-il gérer plusieurs états dans le cas où il y a plusieurs sessions client ?

0 votes

Une bonne réponse, des exemples, une explication abondante et ce que je cherchais. TY. +1

1 votes

Si vous êtes nouveau comme moi, installez les dépendances de la façon dont elles sont mentionnées ici - ianhinsdale.com/code/2013/12/08/

92voto

Aleš Kotnik Points 1237

Pour la communication entre node.js et le serveur Python, j'utiliserais des sockets Unix si les deux processus fonctionnent sur le même serveur et des sockets TCP/IP sinon. Pour le protocole de marshaling, je choisirais JSON ou tampon de protocole . Si Python threadé s'avère être un goulot d'étranglement, envisagez l'utilisation de Twisted Python qui offre la même concurrence événementielle que node.js.

Si vous vous sentez aventureux, apprenez clojure ( clojurescript , clojure-py ) et vous obtiendrez le même langage qui fonctionne et interagit avec le code existant sur Java, JavaScript (node.js inclus), CLR et Python. Et vous obtenez un superbe protocole de marshalling en utilisant simplement les structures de données clojure.

2 votes

Savez-vous si quelque chose comme cela fonctionnera sur Heroku, qui a un système de fichiers éphémère ?

7voto

lanzz Points 19475

Si vous faites en sorte que votre travailleur Python se trouve dans un processus distinct (soit un processus de type serveur à long terme, soit un enfant créé à la demande), votre communication avec lui sera asynchrone du côté de node.js. Les sockets UNIX/TCP et les communications stdin/out/err sont intrinsèquement asynchrones dans node.

6voto

Doug McCall Points 19

J'ai eu beaucoup de succès en utilisant thoonk.js ainsi que thoonk.py . Thoonk exploite Redis (magasin clé-valeur en mémoire) pour vous donner des modèles de flux (pensez à publier/abonner), de file d'attente et de travail pour la communication.

Pourquoi est-ce mieux que les sockets unix ou les sockets tcp directs ? Les performances globales peuvent être légèrement diminuées, mais Thoonk fournit une API vraiment simple qui simplifie la gestion manuelle d'un socket. Thoonk aide également à rendre vraiment trivial l'implémentation d'un modèle de calcul distribué qui vous permet de faire évoluer vos travailleurs python pour augmenter les performances, puisque vous devez simplement créer de nouvelles instances de vos travailleurs python et les connecter au même serveur redis.

6voto

Iftah Points 1892

J'envisagerais aussi Apache Thrift. http://thrift.apache.org/

Il peut faire le lien entre plusieurs langages de programmation, est très efficace et prend en charge les appels asynchrones ou synchrones. Voir toutes les caractéristiques ici http://thrift.apache.org/docs/features/

Le multi-langage peut s'avérer utile pour les projets futurs. Par exemple, si vous souhaitez ultérieurement effectuer une partie de la tâche de calcul en C++, il est très facile de l'ajouter au mélange en utilisant Thrift.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X