Reputation: 788
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
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