I am trying to render a webpage and convert it to an image with Phantomjs.
When I run the phantomjs code directly through terminal it works. When I run the code through a node.js child_process request I keep getting errors such as 'select: invalid argument' - this error loops infinitely, so I have to restart the server to end the process.
Example of my phantomDriver.js:
var page = require('webpage').create(),
system = require('system');
page.viewportSize = {
width: 1920,
height: 1080
};
/**
* Check for required parameters
*/
if (system.args.length < 2) {
console.log('Usage: report.js <some URL>');
phantom.exit();
}
page.open('https://github.com/', function(status) {
console.log('Page Loaded');
page.render('github.png');
phantom.exit();
});
My Meteor request for phantomDriver.js:
var phantomjs = Npm.require('phantomjs');
var spawn = Npm.require('child_process').spawn;
Meteor.methods({
runPhantom: function(options){
command = spawn(phantomjs.path, ['assets/app/phantomDriver.js', '']);
command.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
command.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
command.on('exit', function (code) {
console.log('child process exited with code ' + code);
});
}
});
If I replace 'https://github.com/' with '' in the page.Open() method I get:
child process exited with code 0. It seems that phantomjs is working but something is not quite right with it opening/loading a webpage?
*** Added comment:
It seems then when I run page.open(url, function(status){}) any code inside the page.open function callback never gets executed, something happens prior to that that just loops infinitely <- not 100% sure but what it looks like.
Thank you
Related
I am new to node.js and following some tutorials. In one of them, I execute the following code and expect to shutdown the terminal gracefully which is not the case
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(chunk) {
process.stdout.write('Data! -> ' + chunk);
});
process.stdin.on('end', function() {
process.stderr.write('End!\n');
});
process.on('SIGTERM', function() {
process.stderr.write("Why are you trying to terminate me?!? :-)");
});
console.log("Node is running as process #" + process.pid);
It works fine, but when I issue, from another terminal the following
taskkill /PID 29884 /F
I don't get the function
process.on('SIGTERM', function()....
get executed.
I came across a thread here at
What is the Windows equivalent of process.on('SIGINT') in node.js?
I get the same behavior, killing the process just goes back to the command line
Then I tried to update the code I got from the thread with some code in order to reprint the Data I enter on the console, it is not getting there (I added rl.on("data", function(chunk))
(process.platform === "win32") {
var rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.output.setEncoding('utf8');
console.log("Node is running as process #" + process.pid);
rl.on("data", function(chunk) {
this.output.write('Data! -> ' + chunk);
});
rl.on("SIGINT", function() {
process.emit("SIGINT");
});
};
process.on("SIGINT", function() {
//graceful shutdown
process.exit();
});
The
rl.on("data", function(chunk) {
this.output.write('Data! -> ' + chunk);
});
just sends back 'Data! -> ' string without the text I enter in the console as the case with the 1st code from the tutorial. What is missing?
Of course, In both cases
process.stderr.write("Why are you trying to terminate me?!? :-)");
is not getting executed
Thanks
I'm looking to build a project based on node that will have a few different websocket connections, I'm fine with the code itself for what I want to do but can't seem to get my head around how to start the websocket modules (code already written and moved to a file named ws.js) to run from the main server.js file.
I have tried spawning as a child process but just get
Error: spawn ws.js ENOENT
I have removed all other code from each file to prevent hidden errors, content of the files are below.
Server.js
var child = require('child_process').spawn('node', ['ws.js']);
child.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
child.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
child.on('exit', function (code) {
console.log('child process exited with code ' + code);
});
setTimeout(function() {
child.stdin.write('echo %PATH%');
}, 2000);
ws.js
const Gdax = require('gdax');
const publicClient = new Gdax.PublicClient();
const websocket = new Gdax.WebsocketClient(['BTC-USD', 'ETH-USD']);
websocket.on('message', data => {
/* work with data */
console.log("data received");
});
websocket.on('error', err => {
/* handle error */
});
websocket.on('close', () => {
/* ... */
});
EDIT --------------------------
Thanks for the response below from Elliot server.js now runs without error however the ws.js child never writes to the console so is either not running or failing silently. Any help is appreciated on getting this working.
Cheers
For the console logs, you have to keep in mind that a child process is a new process and does not share a console. You can make it work with spawn(), however, since you are using a child process to execute a nodeJs file, I recommend using child_process.fork() instead of spawn. It is similar to spawn but is specifically used for other nodeJs processes. The benefit is that it makes it much easier for the two processes to communicate.
With that in mind, you can make the following updates:
Server.js:
var child = require('child_process').fork('./ws.js');
child.on('message', function (data) {
console.log('stdout: ' + data);
});
child.on('error', function (data) {
console.log('stderr: ' + data);
});
child.on('exit', function (code) {
console.log('child process exited with code ' + code);
});
ws.js
const Gdax = require('gdax');
const publicClient = new Gdax.PublicClient();
const websocket = new Gdax.WebsocketClient(['BTC-USD', 'ETH-USD']);
websocket.on('message', data => {
/* work with data */
process.send("data received");
});
websocket.on('error', err => {
/* handle error */
});
websocket.on('close', () => {
/* ... */
});
process.send() sends data to its parent process, where a listener (i.e.
child.on('message', callback)) is waiting to receive it.
I have a NodeJS App with Socket Io integration. Now my web page and app both has been implemented but I am facing one issue during execution:
Below is my web page code:
<script>
$(document).ready(function(){
$("#batch")[0].reset();
var socket = io.connect('http://xx.xx.xxx.xx:xxxx',{'forceNew':true });
socket.on('message', function (data) {
var newtext = data;
document.batch.outputtext.value += newtext;
});
socket.on('end', function (data) {
socket.disconnect();
});
});
</script>
And my NodeJS App:
exec_script = function(resp) {
socket.on('connection', function (client) {
console.log('Connection Established');
client.on('disconnect', function () {
console.log('disconnected');
return;
});
var pyshell = new PythonShell('./test.py', options ={ mode: 'text', pythonOptions: ['-u'] });
pyshell.stdout.on('data', function(data) {
client.emit('message', data);
console.log(data);
});
pyshell.end(function(err) {
if (err) throw err;
console.log('End Script');
client.emit('end', 'end');
client.disconnect();
});
});
};
The issue I am facing is that when the Python scripts executes its output is send to browser while my browser status states "Waiting for xx.xx.xxx.xx" and in my FF I see the blue circle circling - that's fine - but even after the Python script has ended and socket disconnected explicitly I still see the browser status as "Waiting for xx.xx.xxx.xx browser title as Connecting with the blue circle rotating?
How can I close and end the connection successfully with the fact that I need the same page in the browser that is I would not navigate the user to some other page?
I tried by using response.end() but the issue I am facing is that if the request data was posted as URL form /today then calling response.end() changes the URL at browser side to http://xx.xx.xxx.xx:xxxx/today leading to a blank / error page which is what I a do not want in my case - the URL should remain as http://xx.xx.xxx.xx:xxxx?
Below is the method I am calling my exec_script method:
router.post('/', function(req, res) {
methods.process(req, res);
});
exports.process = function(req, resp) {
var bname = req.body['date'];
if(typeof req.body['date'] !== "undefined" && req.body['date'] !== null)
{
exec_script(req, resp);
}
};
I am working in node, as it happens via a visual studio code extension. I successfully create child processes and can terminate them on command. I am looking to run code when the process unexpectedly exits, this appears to be what the "exit" event is intended for, but I'm unclear on how to call it, this is the code I am working with, the process runs, but does not detect/log on exit, note that output.append is visual studio code specific version of console.log():
child = exec('mycommand', {cwd: path},
function (error, stdout, stderr) {
output.append('stdout: ' + stdout);
output.append('stderr: ' + stderr);
if (error !== null) {
output.append('exec error: ' + error);
}
});
child.stdout.on('data', function(data) {
output.append(data.toString());
});
Here's four things I have tried that do not work in logging on exit:
child.process.on('exit', function(code) {
output.append("Detected Crash");
});
child.on('exit', function(code) {
output.append("Detected Crash");
});
child.stdout.on('exit', function () {
output.append("Detected Crash");
});
child.stderr.on('exit', function () {
output.append("Detected Crash");
});
Looking at the node.js source code for the child process module, the .exec() method does this itself:
child.addListener('close', exithandler);
child.addListener('error', errorhandler);
And, I think .on() is a shortcut for .addListener(), so you could also do:
child.on('close', exithandler);
child.on('error', errorhandler);
I'm trying to get off the ground with mocha-phantomjs and I seem to be hitting a snag with regards to require. I was hoping other sets of eyes can see what I'm doing wrong.
$ mocha-phantomjs test/index.html
My Site
1) server should be running
Error: Script error for: webpage
http://requirejs.org/docs/errors.html#scripterror
The files in question are fairly small:
https://gist.github.com/cobaltroad/6675855
Here's the spec script in particular:
test.spec.js
describe("My Site", function() {
it("server should be running", function(done) {
require(['webpage'], function(webpage) {
var page = webpage.create();
page.open("http://localhost:8080/", function() {
var title = page.evaluate(function () {
return document.title;
});
title.should.eql('My Title');
console.log("Title: " + title);
phantom.exit();
done();
});
});
}); // server should be running
});
I've tried various forms of define/require and I haven't been able to get it quite right.