web-dev-qa-db-fra.com

Comment puis-je communiquer entre le code python en cours d'exécution et nodejs

J'aimerais que du code python soit exécuté et communique avec un serveur nodejs express. Jusqu'à présent, je peux faire en sorte que mon serveur nodejs appelle des fonctions python via l'un des deux mécanismes, soit pour générer une tâche python, soit pour la faire dialoguer avec un serveur python zerorpc.

Pour le premier, à la http://www.sohamkamani.com/blog/2015/08/21/python-nodejs-comm/ , cela fonctionne:

var express = require( "express" );
var http = require( "http" );
var app = express();
var server = http.createServer( app ).listen( 3000 );
var io = require( "socket.io" )( server );

app.use( express.static( "./public" ) );

io.on( "connection", function( socket ) {

    // Repeat interval is in milliseconds
    setInterval( function() {

        var spawn = require( 'child_process' ).spawn,
        py    = spawn( 'python', [ 'mytime.py' ] ),
        message = '';

        py.stdout.on( 'data', function( data ) {
            message += data.toString();
        });

        py.stdout.on( 'end', function() {
            socket.emit( "message", message );
        });

    }, 50 );
});

Où mytime.py est

from datetime import datetime
import sys

def main():
    now = datetime.now()
    sys.stdout.write( now.strftime( "%-d %b %Y %H:%M:%S.%f" ) )

Et avec zerorpc http://www.zerorpc.io/ , si ce code python est en cours d'exécution:

from datetime import datetime
import sys
import zerorpc

class MyTime( object ):
    def gettime( self ):
        now = datetime.now()
        return now.strftime( "%-d %b %Y %H:%M:%S.%f" )

s = zerorpc.Server( MyTime() )
s.bind( "tcp://0.0.0.0:4242" )
s.run()

Ce code nodejs fonctionne:

var express = require( "express" );
var http = require( "http" );
var app = express();
var server = http.createServer( app ).listen( 3000 );
var io = require( "socket.io" )( server );
var zerorpc = require( "zerorpc" );
var client = new zerorpc.Client();
client.connect( "tcp://127.0.0.1:4242" );

app.use( express.static( "./public" ) );

io.on( "connection", function( socket ) {

    // Repeat interval is in milliseconds
    setInterval( function() {

        client.invoke( "gettime", function( error, res, more ) {
            socket.emit( "message", res.toString( 'utf8' ) );
        } );

    }, 50 );
});

Mais ce que j'aimerais pouvoir faire, c'est que, au lieu d'avoir simplement des fonctions python appelées, je souhaite un processus python séparé en cours d'exécution et l'envoi de messages au serveur nodejs qui les écoute puis les gère. J'ai expérimenté le middleware socketio-wildcard, mais si j'essaie de configurer un serveur python avec zerorpc sur le même port que le serveur nodejs express, l'erreur zmq.error.ZMQError: déjà utilisée .

Je sais que je ne pense pas à cela correctement - je sais que je manque une certaine logique autour de la communication interprocessus en raison de ma naïveté ici - alors s'il existe un meilleur moyen d'envoyer des messages à partir d'un processus python avec un nœud Le serveur écoute, je suis tout ouïe.

Des idées?

Merci d'avance!

7
Dribbler

Pour ceux qui essaient de comprendre cela, voici une solution grâce à Zeke Alexandre Nierenberg

Pour le code de serveur node.js:

var express = require( "express" );
var app = express();
var http = require( "http" );
app.use( express.static( "./public" ) ); // where the web page code goes
var http_server = http.createServer( app ).listen( 3000 );
var http_io = require( "socket.io" )( http_server );

http_io.on( "connection", function( httpsocket ) {
    httpsocket.on( 'python-message', function( fromPython ) {
        httpsocket.broadcast.emit( 'message', fromPython );
    });
});

et le code python qui lui envoie des messages:

from datetime import datetime
from socketIO_client import SocketIO, LoggingNamespace
import sys

while True:
    with SocketIO( 'localhost', 3000, LoggingNamespace ) as socketIO:
        now = datetime.now()
        socketIO.emit( 'python-message', now.strftime( "%-d %b %Y %H:%M:%S.%f" ) )
        socketIO.wait( seconds=1 )

Voilà!

7
Dribbler

J'ai eu quelques problèmes avec la version socketIO ...

alors voici ma solution: 

NodeJS:

   var app = require("express")();
   var http = require('http').Server(app);
   var bodyParser = require('body-parser');

    app.use(bodyParser.json())
    app.post('/',function(req,res){
            var msg=req.body.msg;
            console.log("python: " + msg);
    });

     http.listen(3000, function(){
     console.log('listening...');
     });

sur Python: 

  import requests
  import json

  url = "http://localhost:3000"
  data = {'msg': 'Hi!!!'}
  headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
  r = requests.post(url, data=json.dumps(data), headers=headers)
2
Felipe