Node with Blender/Python; STDIN Causing Hang

52 views
Skip to first unread message

Daniel Scutt

unread,
Jun 27, 2017, 2:55:26 PM6/27/17
to nodejs
I'm not sure where the issue lies. I'm attempting to run a packaged Blender game as a Node child process. I use the stdin and stdout streams to communicate between the two. I've tested it already, and have verified I can send data to and receive data from the Blender game. However, I must call stdin.end() after the initial message is sent, otherwise the program hangs. But if I call stdin.end(), I end that stream and can no longer communicate between the Node process and the game. I intend to do most of my scripting in Javascript, and might ultimately pick up Unity over Blender. I've been using Blender for a number of years, so it's really just old-dog mentality that's keeping me from making the move. But I'm not sure that would solve my issue anyway.

This is the script I use to spawn the Blender game, and send a message to the game (I copied this from an example on Stack Exchange).

//start.js
var spawn = require('child_process').spawn,
    blend    = spawn('test.exe', []),
    data = [1,2,3,4,5,6,7,8,9],
    dataString = '';
blend.stdout.on('data', function(data){
  dataString += data.toString();
});
blend.stdout.on('end', function(){
  console.log('Sum of numbers=',dataString);
});
blend.stdin.write(JSON.stringify(data));
blend.stdin.end();

This is the script I use in the Blender game, in conjunction with the above (also copied, and modified, from the Stack Exchange example).

import bge
import sys, json
import select
cont = bge.logic.getCurrentController()
own = cont.owner
"""
Client Data Handling
"""
def ReadSTDIn():
data = []
if select.select([sys.stdin,],[],[],0.0)[0]:
lines = sys.stdin.readlines()
if len(lines) >= 1:
for line in json.loads(lines[0]):
data.append(line)
return data
def SendSTDOut(data):
print(data+"\n")
return 1
def DataHandler():
lines = ReadSTDIn()
send = ""
for line in lines:
if line == "test":
send = "test sat"
SendSTDOut(send)
return 1

"""
Logic Interval Stuff
"""
def GetLocation():
wp = own.worldPodition()
for coord in wp:
SendSTDOut(coord)
def Interval():
GetLocation()
return 1

def Main():
DataHandler()
Interval()
return 1
Main() 

Danny Tix

unread,
Aug 4, 2017, 2:13:15 AM8/4/17
to nodejs
I'm probably too late to help, but in the chance that it helps anyone else who stumbles across this post, the problem here is that you are using sys.stdin.readlines() in your ReadSTDIn() function. This function will (by design) block the python thread until it receives an end-of-file signal from Node.js via the blend.stdin.end() function call at the end of your sample javascript code. If you want your code to be able to send, process, repeat indefinitely, you will need to use sys.stdin.readline() (without the 's') or just sys.stdin.read(). In either case, you will need to implement some mechanism to signal to your python code when to pause reading and process each message (e.g. a sentinel.)
Reply all
Reply to author
Forward
0 new messages