I am using node.js to monitor a website's API for commands and choose the appropriate child process based on the said command. Only one child process should be running at a time. As of now, child process 1 begins on startup of the node.js script (good). Then, when a command is heard child process 2 starts up (also good), but along with child process 1 still running in the background (not good).
How can I get child process 1 to be terminated on the start of child process 2? I am currently using ("child_process").exec; and my code is mostly working, should I be using ("child_process").fork; or ("child_process").spawn; instead?
I have tried using execFile.kill('SIGTERM'); on startup of child process 2, as well as an else/if statement without any luck. (I'll cut down on the non-essential code below).
const tmi = require('tmi.js');
var exec = require("child_process").exec;
var execFile = require('child_process').exec;
.
.
.
(edited out)
.
.
.
// Register our event handlers (defined below)
client.on('connected', (address, port) => {
client.action('account', 'phrase');
execFile('/path/script.py, function(error, stdout, stderr) {
if (error) {
throw error;
return;
}
});
});
client.on('chat', (channel, user, message, self) => {
if (message === '!exec') {
execFile.kill('SIGTERM'); //to try and terminate child process 1 above
exec('/path/script.py , function(error, stdout, stderr) {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
});
}
});
I have worked on this issue for a while without much progress. Any and all insight is appreciated!
const tmi = require('tmi.js');
var exec = require("child_process").exec;
var execFile = require('child_process').exec;
var child;
.
.
.
(edited out)
.
.
.
// Register our event handlers (defined below)
client.on('connected', (address, port) => {
client.action('account', 'phrase');
child = execFile('/path/script.py, function(error, stdout, stderr) {
if (error) {
throw error;
return;
}
});
});
client.on('chat', (channel, user, message, self) => {
if (message === '!exec') {
child.kill(); //kills the child process.
}
});
Here is the example code. The below code starts the mongo server with child process and after 10 secs it will get killed.
const child = require('child_process');
const ls = child.exec('mongod --dbpath ~/Documents/myown/learning/mongo', (err, stdout, stderr) => {
if(err) {
console.log(err);
}
else {
console.log(stdout);
}
});
setTimeout(() => {
ls.kill();
}, 10000);
Related
I would like to send "Hello world" from one nodejs server to another using node-serialport. I have verified that the radios connecting the two are connected and sending info because they keep displaying buffer information after running my current code.
here is what I have so far.
server1
// Import dependencies
const SerialPort = require("serialport");
const Readline = require("#serialport/parser-readline");
var sf = require('sf');
//SerialPort.list(function (err, results) {
// if (err) {
// throw err;
// }
SerialPort.list().then(ports => {
ports.forEach(function(port) {
console.log(port.path);
console.log(port.pnpId);
console.log(port.manufacturer);
});
});
// Defining the serial port
const port = new SerialPort('COM3',{baudRate: 9600}, function (err) {
if (err) {
return console.log('Port Error: ', err.message)
}
})
port.write('main screen turn on', function(err) {
if (err) {
return console.log('Error on write: ', err.message)
}
console.log('message written')
})
// Read data that is available but keep the stream in "paused mode"
port.on('readable', function () {
console.log('Data:', port.read())
})
// Switches the port into "flowing mode"
port.on('data', function (data) {
console.log('Data:', data)
})
// Pipe the data into another stream (like a parser or standard out)
const lineStream = port.pipe(new Readline())
lineStream.on('data', console.log)
server 2
// Import dependencies
// in Ubuntu need to run command: sudo chmod 666 /dev/ttyS0 to open port for use
const SerialPort = require("serialport");
const Readline = require("#serialport/parser-readline");
var stoploop = true;
// Defining the serial port
const port = new SerialPort('/dev/ttyUSB0', function (err) {
if (err) {
return console.log('Error: ', err.message)
}
})
port.write('chicken butt', function(err) {
if (err) {
return console.log('Error on write: ', err.message)
}
console.log('message written')
})
// port.write("hello?");
// Read data that is available but keep the stream in "paused mode"
port.on('readable', function () {
console.log('Data:', port.read())
})
// Switches the port into "flowing mode"
port.on('data', function (data) {
console.log('Data:', data)
})
// Pipe the data into another stream (like a parser or standard out)
const lineStream = port.pipe(new Readline())
any help or even an example of how to send hello world between the two would be greatly appreciated! please let me know if any more info is needed.
edit : I recently tried doing something like
port.on('data', (data) => {
try {
console.log(data.toString());
} catch (err) {
console.log('Oops');
}
});
this is taking data that used to appear as <buffer # # # # #> and turning it into an odd string like "(
)))) ) ) )))
!)☺)!))) ) )
)(☺!�"
I found the answer myself!
I was using the wrong baudRate, and also needed to stringify the data being sent as a JSON string
Is it possible to run cmd.exe and execute some command with Electron.js?
If yes then how can I do this?
In your main.js file, you can put the following code:
//Uses node.js process manager
const electron = require('electron');
const child_process = require('child_process');
const dialog = electron.dialog;
// This function will output the lines from the script
// and will return the full combined output
// as well as exit code when it's done (using the callback).
function run_script(command, args, callback) {
var child = child_process.spawn(command, args, {
encoding: 'utf8',
shell: true
});
// You can also use a variable to save the output for when the script closes later
child.on('error', (error) => {
dialog.showMessageBox({
title: 'Title',
type: 'warning',
message: 'Error occured.\r\n' + error
});
});
child.stdout.setEncoding('utf8');
child.stdout.on('data', (data) => {
//Here is the output
data=data.toString();
console.log(data);
});
child.stderr.setEncoding('utf8');
child.stderr.on('data', (data) => {
// Return some data to the renderer process with the mainprocess-response ID
mainWindow.webContents.send('mainprocess-response', data);
//Here is the output from the command
console.log(data);
});
child.on('close', (code) => {
//Here you can get the exit code of the script
switch (code) {
case 0:
dialog.showMessageBox({
title: 'Title',
type: 'info',
message: 'End process.\r\n'
});
break;
}
});
if (typeof callback === 'function')
callback();
}
Now, you can execute arbitary command (the example is from windows command prompt, but the funtion is universal) by calling:
run_script("dir", ["/A /B /C"], null);
The parameters of your command are in fact an array ["/A /B /C"], and the last parameter is callback to be executed, you can provide null as parameter, if special callback function is not needed.
it is possible by using node child_process , You can use this function:
const exec = require('child_process').exec;
function execute(command, callback) {
exec(command, (error, stdout, stderr) => {
callback(stdout);
});
};
// call the function
execute('ping -c 4 0.0.0.0', (output) => {
console.log(output);
});
and there are many packages in npm for this topic to .
I am working on a loopback project where I need to run a background job. Spawn node child process. Since I am beginner, documentation is little confusing. https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options
parent.js
const path = require("path");
const spawn = require('child_process').spawn;
let child = spawn('node', [__dirname + '../../worker/worker.js']);
child.stdout.on('data', function (data) {
console.log('data available ' + data);
});
child.stderr.on('data', function (data) {
console.log('There was an error: ' + data);
});
worker.js
function jobListener() {
let query = { jobname: "countProvider"}
let result = Job.findOne({ where: query }, function(err, instance) {
if(err) {
console.log('Error', err);
}
// console.log(instance);
});
while (!result) {
console.log(result);
// await sleep(5000);
console.log('checking for job in mongodb with a delay of 5 seconds');
}
if(result) {
fetchProcedureRequest();
}
}
jobListener();
function fetchProcedureRequest() {
console.log('Fetching pREquest');
}
What I am trying to achieve is I am getting the data in child process. But how can I close/exit the process when data is available in parent. Somebody please help and any suggestion will be really appreciated.
May be you can use this, found here How to kill childprocess in nodejs?
var proc = require('child_process').spawn('mongod');
proc.kill('SIGINT');
I am trying to kill a child process I have running within my server. Basically the child process runs johnny-five code I've written in an online terminal in React to my server. When I run the child process, the code works great but if I want to kill the child process I cant do so without stopping the server. I've tried doing so with Control-C and .exit() but neither seem to work.
codeRouter
.post('/codeAPI', (req, res) => {
console.log(req.body)
let fileName = `johnnyFiles/${req.body.currentFile}`
fs.writeFileSync(fileName, req.body.currentCode, (err) => {
if (err) throw err
})
let id = shortid.generate()
let fileObject = {
fileName: req.body.currentFile,
fileContents: req.body.currentCode,
ID: id
}
data = [fileObject, ...data]
fs.writeFileSync('data/fileData.json', JSON.stringify(data), (err) => {
if (err) throw err
})
res.json(data)
///////////////////////////////////////////
let nodeSpawn = spawn('node', [fileName], {
//detached: true,
shell: true
})
nodeSpawn.stdout.on('data', (data) => {
console.log("OUTPUT", data.toString())
})
nodeSpawn.stderr.on('data', (data) => {
console.log("ERRORS", data.toString())
})
nodeSpawn.on('exit', (code) => {
console.log(`Child exited with code ${code}`)
nodeSpawn.kill('SIGINT')
})
})
`
You can use the linux command line.
To see the running processes use the command, use:
pgrep node
To kill the process you can use:
kill <pid>
Or to force the shutdown
kill -9 <pid>
Or if you want kill all node processes
kill $(pgrep node)
I'm trying to create a simple script to run a few node files, these files are just api's for a quote database , Authentication , and a twitch bot.
The Quote and Authentication work just find however they twitch bot does not it says its connected to the server but when it goes to execute any commands it gets a unhandled promise rejection or some such error
However when I run the twitch bot separately in its own terminal session and not from the script it works just fine with no thrown errors.
Why will it work from a separate session that I create but not from a child_process?
note: I have had the child_process start up a new shell and its still the same issue
The process script:
const exec = require('child_process').exec;
const spawn = require('child_process').spawn
// I think twtich bot process has an issue without how much
//data is being passed to stdout or stderr and I need
//to specify how much data is allowed
twitchBot = exec('node ./twitchbot-api/index.js',
function(error, stdout, stderr){
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if(error !== null){
console.log('exec error: ' + error);
}
})
twitchBot.stdout.on('data', (data) => {
console.log(`twitchBot stdout:\n${data}`);
});
//whenver I recieve an error from quoteDataBase it also displays in the parent process
twitchBot.stderr.on('data', (data) => {
console.error(`twitchBot stderr:\n${data}`);
});
//this throws an error the first time I try a command saying not connected to server , I think I need to do this as exec
// let twitchBot = spawn('node ./twitchbot-api/index.js',{
// stdio: 'inherit',
// shell: true,
// detached: true,
// })
// //twitchBot.unref();
// twitchBot.on('error', (error)=>{
// console.log(`the erorr ${error}`)
// })
//starts up a child exec process for my quotes database
let quoteDataBase = exec('node ./quotes-api/index.js',
function(error, stdout, stderr){
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if(error !== null){
console.log('exec error: ' + error);
}
})
//whatever the child exec process quoteDatabase pushs to the standard out (console) displays on the parent process
// aka the terminal I run apiStart from
quoteDataBase.stdout.on('data', (data) => {
console.log(`quoteDataBase stdout:\n${data}`);
});
//whenver I recieve an error from quoteDataBase it also displays in the parent process
quoteDataBase.stderr.on('data', (data) => {
console.error(`quoteDataBase stderr:\n${data}`);
});
//starts up a child process for my user Authentication
let AuthenDataBase = exec('node ./authen-api/index.js',
function(error, stdout, stderr){
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if(error !== null){
console.log('exec error: ' + error);
}
})
And then the twitch bot code:
const tmi = require('tmi.js')
const haikudos = require('haikudos')
require('dotenv').config()
require('es6-promise').polyfill();
require('isomorphic-fetch');
// Valid commands start with:
let commandPrefix = '!'
// Define configuration options:
let opts = {
identity: {
username: process.env.user,
password: process.env.pass
},
channels: [
"dshrops1"
]
}
// These are the commands the bot knows (defined below):
let knownCommands = { echo, haiku, quote }
// Function called when the "echo" command is issued:
function echo (target, context, params) {
// If there's something to echo:
if (params.length) {
// Join the params into a string:
const msg = params.join(' ')
// Send it back to the correct place:
sendMessage(target, context, msg)
} else { // Nothing to echo
console.log(`* Nothing to echo`)
}
}
// Function called when the "haiku" command is issued:
function haiku (target, context) {
// Generate a new haiku:
haikudos((newHaiku) => {
// Split it line-by-line:
newHaiku.split('\n').forEach((h) => {
// Send each line separately:
sendMessage(target, context, h)
})
})
}
async function quote (target, context){
//cant deploy this on AWS yet Untill I deploy my database api as well.
let quote = await fetch('http://localhost:3006/random').then(resp =>resp.text())
sendMessage(target,context,quote)
}
// Helper function to send the correct type of message:
function sendMessage (target, context, message) {
if (context['message-type'] === 'whisper') {
client.whisper(target, message)
} else {
client.say(target, message)
}
}
// Create a client with our options:
let client = new tmi.client(opts)
// Register our event handlers (defined below):
client.on('message', onMessageHandler)
client.on('connected', onConnectedHandler)
client.on('disconnected', onDisconnectedHandler)
// Connect to Twitch:
client.connect()
// Called every time a message comes in:
function onMessageHandler (target, context, msg, self) {
if (self) { return } // Ignore messages from the bot
// This isn't a command since it has no prefix:
if (msg.substr(0, 1) !== commandPrefix) {
console.log(`[${target} (${context['message-type']})] ${context.username}: ${msg}`)
return
}
// Split the message into individual words:
const parse = msg.slice(1).split(' ')
// The command name is the first (0th) one:
const commandName = parse[0]
// The rest (if any) are the parameters:
const params = parse.splice(1)
// If the command is known, let's execute it:
if (commandName in knownCommands) {
// Retrieve the function by its name:
const command = knownCommands[commandName]
// Then call the command with parameters:
command(target, context, params)
console.log(`* Executed ${commandName} command for ${context.username}`)
} else {
console.log(`* Unknown command ${commandName} from ${context.username}`)
}
}
// Called every time the bot connects to Twitch chat:
function onConnectedHandler (addr, port) {
console.log(`* Connected to ${addr}:${port}`)
}
// Called every time the bot disconnects from Twitch:
function onDisconnectedHandler (reason) {
console.log(`Womp womp, disconnected: ${reason}`)
process.exit(1)
}
Sorry About any formatting issues
Despite all the issues that might be wrong with the twitch bot it does work fine when I run it from a separate terminal I am curious as to why it does work from the script and what I can do.
notes: I figured it might have to do with the twitch api being a IRC.