web-dev-qa-db-ja.com

実行中のpythonコードとnodejs

いくつかのpythonコードを実行し、nodejsエクスプレスサーバーと通信します。これまでのところ、nodejsサーバーにpython関数を呼び出して、 pythonタスクを生成するか、zerorpc pythonサーバーと通信させるための2つのメカニズムのいずれか。

最初の場合、 http://www.sohamkamani.com/blog/2015/08/21/python-nodejs-comm/ 、これは動作します:

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

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

Zerorpc http://www.zerorpc.io/ で、このpythonコードが実行されている場合:

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

このnodejsコードは機能します:

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

しかし、私ができるようにしたいのは、単にpython関数を呼び出すのではなく、別のpythonプロセスを実行してメッセージを送信するミドルウェアsocketio-wildcardで実験しましたが、同じポートでzerorpcを使用してpythonサーバーを設定しようとすると、nodejsサーバーに接続します。 nodejsエクスプレスサーバー、zmq.error.ZMQError:アドレスは既に使用中ですエラー。

私はこの正しいことを考えていないことを知っています-私はここで私のナイーブのためにプロセス間通信に関するいくつかのロジックを見逃していることを知っています-したがって、python nodejsサーバーがリッスンしているプロセス、私はすべて耳です。

何か案は?

事前に感謝します!

13
Dribbler

これを理解しようとしている人のために、 Zeke Alexandre Nierenberg のおかげで解決策があります

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

そして、メッセージを送信するpythonコード:

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 )

ほら!

10
Dribbler

SocketIOバージョンに問題がありました...

だから、これは私の解決策です:

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

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)
3
Felipe