Leonardo Rick
Leonardo Rick

Reputation: 788

Keep comunication with python script running on server

This is what I developed so far. First, my websocket server:

// app.js
const spawn = require('child_process');
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 8080 })

wss.on('connection',ws => {
  ws.on('message', message => {
    const python = spawn('python', ['-u', 'main.py', message])
    python.stdout.on('data', function (data) {
      // Pipe data from python script ...
      dataToSend = data.toString('utf8');
      ws.send(dataToSend)
     });
     python.on('error', err => {
       console.log(err)
     })
  })
  ws.on('close', () => {
    console.log('Client has disconected')
  })
}).on('error', err => {
  console.log(err)
})

It basics uses child_process to spawn a python script passing a message that was sent from client. -u is passed in order to flush python script prints, so it can be streamed out on python.stdout and sent to client.

This is my python script that is being invoked from app.js websocket server:

# main.py
import time, sys
i = int(sys.argv[1])
while i > 0:
    print(i)
    i-=1
    time.sleep(1)
    # this while is just anexemple of some pre-script process
    # (for exemple, signin on user account)

# after signin...
print('input something from client: ')
x = input()

while True:
    print(x)
    time.sleep(1)
    # use input x variable
    # here is where my code happens and the program keeps executing
    pass

As you can see, I'm using message passed on spawn() from server to keep my first while alive. It's just an exemple that I will need this kind of input from user.

Keep your atention on x = input() because that is my main problem

And finally, my client websocket

// client.js
const WebSocket = require('ws');
let socket = new WebSocket("ws://localhost:8080");

socket.onopen = function(e) {
    let someClientInfo = 2
    console.log("sending data...");
    socket.send(someClientInfo);

};

socket.onmessage = function(event) {
    console.log('Output of python script: ' + event.data.toString('utf-8'));
};

socket.onerror = function(event) {
    console.log(event);
};

It basics pass this first argument someClientInfo, and then receive python script output like this:

sending data...

Output of python script: 2 

Output of python script: 1

Output of python script: input something from client:

Of course, when client receive this last line, it keeps getting stuck because he can't input anything from his side. He's just receiving a stream of outputs from python.

Anyone knows if it's possible to pass this second input to my running python script? I'm starting to think that maybe it's impossible but I can't thing about another way to do that. If it is something that child_process can't do, what way should I look for?

My main purpose is to keep an alive communication with an python script running on server, so I can pass this inputs from client to python.

I want to be able to disconnect from this socket, and then, connect again and keep receiving python script outputs. So far I couldn't find a way to do that too.

My main script can't be inside the server code (maybe if you tought about a basic implementation of flask, or something like that), because I want to be able to start multiple scripts and each client user should be able to keep iteracting with his own python script running on server. Each user will have his own main.py

So far I didn't tought about how I'll keep all this processess running on server, or even if it's safe to do something like that. Any advice about that will be very apreciated and I'll be very thankfull about too.

Upvotes: 1

Views: 410

Answers (1)

Yajat Vishwakk
Yajat Vishwakk

Reputation: 80

You might want to check out https://www.npmjs.com/package/python-shell You can spawn a python instance on node.

Upvotes: 1

Related Questions