webentwicklung-frage-antwort-db.com.de

Wie kann ich zwischen laufendem Python-Code und nodejs kommunizieren?

Ich möchte, dass ein bisschen Python-Code läuft und mit einem nodejs-Express-Server kommuniziert. Bisher kann ich meinen nodejs-Server dazu bringen, Python-Funktionen über einen von zwei Mechanismen aufzurufen, entweder um eine Python-Task zu erzeugen oder um sie mit einem Python-Server mit Zerorpc zu sprechen.

Zum einen, a la http://www.sohamkamani.com/blog/2015/08/21/python-nodejs-comm/ , das funktioniert:

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 );
});

Wo ist mytime.py

from datetime import datetime
import sys

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

Und mit zerorpc http://www.zerorpc.io/ , falls dieser Python-Code läuft:

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()

Dieser nodejs-Code funktioniert:

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 );
});

Was ich jedoch gerne tun könnte, ist, statt nur Python-Funktionen aufzurufen, einen separaten Python-Prozess auszuführen und Nachrichten an den nodejs-Server zu senden, der auf sie wartet und sie dann behandelt. Ich habe mit Middleware socketio-wildcard experimentiert, aber wenn ich versuche, einen Python-Server mit zerorpc am selben Port wie der nodejs-Express-Server einzurichten, wird der Fehler zmq.error.ZMQError: Adresse bereits verwendet angezeigt .

Ich weiß, dass ich nicht richtig darüber nachdenke - ich weiß, dass mir wegen meiner Naivität hier eine gewisse Logik in Bezug auf die Kommunikation zwischen Prozessen fehlt. Wenn es also einen besseren Weg gibt, um das Senden von Nachrichten über einen Python-Prozess mit einem Knoten zu tun Server hören, ich bin ganz Ohr.

Irgendwelche Ideen?

Vielen Dank im Voraus!

7
Dribbler

Für diejenigen, die versuchen, dies herauszufinden, hier eine Lösung dank Zeke Alexandre Nierenberg

Für den Servercode 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 );
    });
});

und der Python-Code, der Nachrichten sendet:

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

Ich hatte einige Probleme mit SocketIO-Version ...

also das ist meine Lösung: 

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...');
     });

auf 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