I'm trying to pipe the console output of a child Python process to a parent Node.js process. I'm able to spawn a Python process successfully, and the output from the Node parent process successfully is outputted live to the webpage.
However, I can't send the output from the child process (Python script). The Python script successfully launches if I use the parameter "stdio: 'inherit'", but I require "stdio: 'pipe'", to output the terminal, and for some reason it doesn't work.
Server Code
app.post('/clientwebpageoutput', function(req,res)
{
var io = require('socket.io')(http);
var child = require('child_process');
var events = require('events');
var eventEmitter = new events.EventEmitter();
eventEmitter.on('logging', function(message) {
io.emit('log_message', message);
});
io.on('connection', function(socket){
console.log('Before process begins');
var python_process = child.spawn( 'python3', ['snowboymultiplemodels.py'], {stdio: 'pipe'});
var chunk = '';
python_process.stdout.on('data', function(data){
chunk += data
socket.emit('newdata', chunk);
} );
python_process.stderr.on('data', function (data) {
console.log('Failed to start child process.');
})
});
// Override console.log
var originConsoleLog = console.log;
console.log = function(data) {
eventEmitter.emit('logging', data);
originConsoleLog(data);
};
res.render('clientwebpageoutput'); //,output);
});
Client (successfully outputs stderr):
<script src="/socket.io/socket.io.js"></script>
<script>
$(function () {
var socket = io();
socket.on('log_message', function(msg){
$('#messages').append($('<li>').text(msg));
});
});
</script>
Why does the process not spawn? The terminal always shows the error message created above in stderr ("Failed to start child process").
Related
I believe this is a simple question: I have a websocket server (index.js) that opens a serial port when the browser (index.html) is loaded. I have a scale connected via USB (COM3). From the browser I want to send commands to the scale and receive data back to the browser. My node version is v7.7.4 and npm version is 4.1.2. I have also NPM installed serialport and ws.
index.js
var SerialPort = require('serialport');// include the library
//var SerialPort = serialport.SerialPort; // make a local instance of it
var WebSocketServer = require('ws').Server;
var SERVER_PORT = 8080; // port number for the webSocket server
var wss = new WebSocketServer({port: SERVER_PORT}); // the webSocket server
var connections = new Array; // list of connections to the server
wss.on('connection', handleConnection);
// get port name from the command line:
portName = process.argv[2];
var myPort = new SerialPort(portName, {
baudRate: 9600,
// look for return and newline at the end of each data packet:
parser: SerialPort.parsers.readline("\n")
});
myPort.on('open', showPortOpen);
myPort.on('data', sendSerialData);
myPort.on('close', showPortClose);
myPort.on('error', showError);
// This function broadcasts messages to all webSocket clients
function broadcast(data) {
for (myConnection in connections) { // iterate over the array of connections
connections[myConnection].send(data); // send the data to each connection
}
}
function sendToSerial(data) {
myPort.write(" From: index.js:sendToSerial "+data);
console.log("sendToSerial (index.js): " + data);
// if there are webSocket connections, send the serial data
// to all of them:
if (connections.length > 0) {
broadcast(data);
}}
function handleConnection(client) {
console.log("New Connection"); // you have a new client
connections.push(client); // add this client to the connections array
client.on('message', sendToSerial); // when a client sends a message,
client.on('close', function() { // when a client closes its connection
console.log("connection closed"); // print it out
var position = connections.indexOf(client); // get the client's position in the array
connections.splice(position, 1); // and delete it from the array
});
}
function showPortOpen() {
console.log(portName+' port open. Data rate: ' + myPort.options.baudRate);
}
function sendSerialData(data) {
myPort.write(" From: index.js:sendSerialData "+data);
myPort.write("sendSerialData "+data);
console.log("sendSerialData "+data);
}
function showPortClose() {
console.log('port closed.');
}
function showError(error) {
console.log('Serial port error: ' + error);
}
and index.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.8/p5.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.8/addons/p5.dom.js"></script>
<script type="text/javascript">
var text; // variable for the text div you'll create
var socket = new WebSocket("ws://localhost:8080");
function setup() {
// The socket connection needs two event listeners:
socket.onopen = openSocket;
socket.onmessage = showData;
// make a new div and position it at 10, 10:
text = createDiv("xxSensor reading:");
text.position(10,10);
}
function openSocket() {
text.html("Socket open");
socket.send("Hello websocket server - from index.html");
}
function showData(result) {
// when the server returns, show the result in the div:
text.html("Sensor reading: " + result.data);
xPos = int(result.data); // convert result to an integer
text.position(xPos, 10); // position the text
}
I have tried SERVER_PORT = 8081 with the same results.
I am able to see info from index.html in the cmd "node index.js COM3" but the command myPort.write does not get to the index.html browser.
I get:
C:\Users\pmfoo\nodeSerialExample>node index.js COM3
COM3 port open. Data rate: 9600
New Connection
sendToSerial (index.js): Hello websocket server - from index.html
sendSerialData 277.5 g
sendSerialData
where 277.5 g is the output from the scale on COM3.
and in the browser:
Sensor reading: Hello websocket server - from index.html
I followed Tom Igoe's tutorial https://itp.nyu.edu/physcomp/labs/labs-serial-communication/lab-serial-communication-with-node-js/ with only partial results. I cannot write from index.js to index.html nor can I send a command via index.js to the scale. This scale command ("ON" or "OFF" or "PSN") is seen by index.js. Can anyone help me solve these 2 communication problems?
I'm trying to recreate the functionality of a hardware serial server with Node and it's actually working, but I'm getting errors from socket instances that have been closed.
Here's a simplified version of the app to show what I'm doing...
var net = require('net');
var SerialPort = require('serialport');
var connectionCounter = 0;
var port = new SerialPort('/dev/ttyUSB0', function () {
var server = net.createServer();
server.on('connection',function(socket) {
connectionCounter++;
var connNumber = connectionCounter;
socket.on('error', function () {
console.log('socket ' + connNumber + ' errored');
});
socket.on('data', function(data) {
port.write(data);
});
port.on('data', function(data) {
socket.write(data);
});
});
server.listen(8887, '127.0.0.1');
}
});
So the first chunk of code that's sent into the 8887 port works fine, and it returns the data back out through the socket. The errors start on the second chunk. In the example, I'm keeping a count of the socket instances and outputting the socket instance number with the error. So as the program runs, the number of sockets instances keeps going up. The most recent instance will eventually handle the data, but I can't figure out what I need to delete to clean up all of the previous socket instances so they'll stop trying to process the incoming data.
I've tried socket.end() and socket.destroy(), but those don't seem to work . Do I need to go as far as deleting the server itself and recreating it?
If anyone ever finds this and cares about what was going wrong, I was setting an event listener on the serialport object every time a new net socket was created. So even though I was deleting the socket every time it was closed, the serialport listener was trying to send data to all of the old deleted sockets. So the solution was to removeListeners from the serialport object upon closing the net socket.
you can use array for storing sockets later on you can delete. this is sample code hope you got the idea
var net = require('net');
var SerialPort = require('serialport');
var connectionCounter = 0;
var mySockets = [];
var port = new SerialPort('/dev/ttyUSB0', function () {
var server = net.createServer();
server.on('connection',function(socket) {
mySockets.push(socket);
connectionCounter++;
var connNumber = connectionCounter;
socket.on('error', function () {
console.log('socket ' + connNumber + ' errored');
});
socket.on('data', function(data) {
port.write(data);
});
port.on('data', function(data) {
socket.write(data);
});
});
server.listen(8887, '127.0.0.1');
}
//get the sockets you want to delete
var s = mySockets.pop();
s = null;
});
I am connecting BBB and a set of arduinos over the serial port (ttyO2).
I have an array to be sent from BBB to a set of arduinos.
I need to make the BBB sends a request and wait for a reply from one of the arduinos, but if no arduino replies within an interval, the BBB must send the following value in the array.
I have the connection and arduinos ready for their jobs.
The problem is that the BBB will listen on the port and complete the execution of the code at the same time. I need to make it listen for a specific time, if data received=> process it; else complete the following part of code (send the remaining part of the array). This job need to be in a loop.
I have been trying to use setTimeout, recursion, but with no success!
I am using the following code to listen and write on ttyO2:
` var b = require('bonescript');
//opening the serial port
var SerialPort = require("serialport").SerialPort
var serialPort = new SerialPort('/dev/ttyO2', {
baudrate: 115200
});
var i = 0;
serialPort.on("open", function () {
console.log('opened');
serialPort.on('data', function(data) {
console.log('data received: ' + data);
serialPort.write( i + "\n", function(){});
});
});
serialPort.on("data", function (data) {
console.log("here: "+data);
});
`
var b = require('bonescript');
//opening the serial port
var SerialPort = require("serialport").SerialPort;
var serialPort = new SerialPort('/dev/ttyO2', {
baudrate: 115200
});
var i = 0;
var waiting_interval = 5000;
var slaves = ["S1", "S2" , "S3", "S4", "S5"];
serialPort.on('open',function my(){
console.log("opened");
serialPort.on('data', function listenToSlaves(data){
console.log("returned: " + data);
});
writeToSlaves();
});
function writeToSlaves(){
// setInterval(serialPort.write(slaves[i], function(){ console.log("I
wrote to slave: " + i)}), 5000);
serialPort.write(slaves[i], function(){ });
console.log("I wrote to slave: " + i);
if(i<slaves.length - 1) i++;
else i=0;
setTimeout(writeToSlaves, waiting_interval);
}
I'm trying to active an RFID reader through node.js and then send the tag back.
It works great. It reads the tag, responds with an ID, then send the ID to the pinging node client.
However, every time the node.JS program picks up a set of data from an RFID tag, after it sends, it closes down with the following error:
events.js:72
throw er; // Unhandled 'error' event
^
Error: EBADF, read
This causes the node process to quit all the time. What could be the problem here?
My code is the following;
// Socket.io server details
var io = require('socket.io').listen(3000);
// Serialport plugin declared and made a serialport variable
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
// Variable containing technical USB port details
var serialPort = new SerialPort("/dev/ttyUSB0",
{baudrate: 2400, parser: serialport.parsers.readline("\n")},
false); // this is the openImmediately flag [default is true]
io.sockets.on('connection', function (socket) {
console.log('user connected');
socket.on('ping', function (data) {
serialPort.open(function () {
// Open notification
console.log('open');
//Start listening
serialPort.on('data', function(data) {
// If content is empty, filter out
if (data.trim() !== '') {
line = data;
//Execute function again, get tag, handle tag and end process
serialPort.close(function () {
console.log('De uiteindelijke tag is ' + data);
console.log('Ping received with data: ' + data);
socket.emit('pong', data);
console.log('closing');
});
console.log('hallo');
}
});
});
});
});
Add a listener to handle the error in the serial port, like the code below:
serialPort.on('error', function(error) {
console.log('The error: '+error);
//...
});
I write some code example that identifi connected users via socket.io... So now I must write a code on index page to comunicate with users.
The code is below and HOW to send a message to user[1] "Welcome" and for user[2] "HI men" and also limit connection fr 2 users. so when 2 user connected then anybody else cant connect..
Index.html:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
var users;
socket.on('hello', function (data) {
console.log(data.hello);
});
socket.on('listing', function (data) {
users = data;
});
socket.on('chat', function (message) {
console.log(message);
});
socket.on('message', function (message) {
console.log(message);
});
function chat (message) {
socket.emit('chat', message);
}
function message (user, message) {
socket.emit('message', {
user: user,
message: message
});
}
</script>
app.js
var express = require('express');
var app = express.createServer();
var io = require('socket.io').listen(app);
app.listen(3000);
app.use(express.static(__dirname));
var users = {};
var userNumber = 1;
function getUsers () {
var userNames = [];
for(var name in users) {
if(users[name]) {
userNames.push(name);
}
}
return userNames;
}
io.sockets.on('connection', function (socket) {
var myNumber = userNumber++;
var myName = 'user#' + myNumber;
users[myName] = socket;
socket.emit('hello', { hello: myName });
io.sockets.emit('listing', getUsers());
socket.on('chat', function (message) {
io.sockets.emit('chat', myName + ': ' + message);
});
socket.on('message', function (data) {
users[data.user].emit('message', myName + '-> ' + data.message);
});
socket.on('disconnect', function () {
users[myName] = null;
io.sockets.emit('listing', getUsers());
});
});
app.listen(process.env.PORT);
You can start by taking a look at how to configure authorization with Socket.io. The handshakeData provided by the callback can be modified there (ie: add a username property), and any changes will be accessible via socket.handshake in your app.js (via the object passed in to the callback for io.sockets.on('connection',..). Using request header information that's also accessible from the handshakeData, you can set user values within the authorization callback (ie: from a database) so you can identify the user for the given socket in your app.js.
Here's a similar example
I know it has been a long time since you asked this, but just 4 days ago I published a module for node js, express and socket.io which manages that exactly thing you wanted. Check the Usage and Example; I hope you will find this module helpful!
You can install it via NPM socket.io.users This is a node js module for socket.io applications. One user per client.
Some of the usage code:
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var socketUsers = require('socket.io.users');
// ...
socketUsers.Session(app); // IMPORTANT !
// ...
var rootIo = require('socket.io')(server); // default '/' as namespace.
var chatIo = rootIo.of('/chat');
var rootUsers = socketUsers.Users; /* default '/' as namespace.
Each namespace has ITS OWN users object list,
but the Id of a user of any other namespace may
have the same value if request comes from the same client-machine-user.
This makes easy to keep a kind of
synchronization between all users of all the different namespaces. */
var chatUsers = socketUsers.Users.of('/chat'); //
rootIo.use(socketUsers.Middleware());
/* IMPORTANT but no errors if you want
to skip it for a io.of(namespace)
that you don't want the socket.io.users' support. */
chatUsers.use(socketUsers.Middleware());
chatUsers.on('connected',function(user){
console.log(user.id + ' has connected to the CHAT');
user.store.username = 'username setted by server side'; /*at the store
property you can store any type of properties
and objects you want to share between your user's sockets. */
user.socket.on('any event', function(data){
/*user.socket is the current socket, to get all connected sockets from this
user, use: user.sockets */
});
chatIo.emit('set username',user.store.username);
});
rootUsers.on('connected',function(user){
console.log('User has connected with ID: '+ user.id);
});
rootUsers.on('connection',function(user){
console.log('Socket ID: '+user.socket.id+' is user with ID: '+user.id);
});
rootUsers.on('disconnected',function(user){
console.log('User with ID: '+user.id+'is gone away :(');
});
//...server.listen blabla..