I am writing code to create an online c++ compiler in node.js environment.Using spawn function i created a child process which will compile the code and execute it and send the output back to the user.
But i need to send input to the running c++ program . I used child.stdin.write('data');
for sending data to child but i think cin in the program is not receiving the input .
Please help me to send the input to the running c++ code.
Thanks.
1.Create a file with input data.
2.Create a ReadStream opening input file.
3.Pipe the ReadStream with childprocess.stdin.
file=fs.createReadStream('input.txt',{encoding:'utf8'});
file.pipe(childprocess.stdin);
This worked for me .
You should probably use either cluster, or fork if you want to pass messages... if you do this, node will setup IPC for you to be able to communicate via process.send
Alternatively, you could use a pub/sub system for communication channels (Redis works well for this), this is also your best bet if you need communications across servers.
Below is an example of an older work script...
var env = process.env.NODE_ENV || 'dev';
var cluster = require("cluster");
//TODO: need to adjust to use domains for this work
process.on('uncaughtException', function (err) {
console.error('GENERAL EXCEPTION IN %s: %s', process.env.WORKER_TYPE || 'MASTER',err);
if (err.stack) console.error(err.stack);
if (cluster.isWorker) {
//process.send notifies the parent process of the error
process.send({
err: {
"str": err && err.toString() || "unknown error"
,"message": err && err.message || null
,"stack": err && err.stack || null
}
});
}
process.nextTick(function(){
process.exit(666);
});
});
if (cluster.isMaster) startMaster();
if (cluster.isWorker) startWorker();
function startMaster() {
createWorker("foo");
createWorker("bar");
}
function createWorker(workerType) {
var worker = cluster.fork({"WORKER_TYPE":workerType}); //passes environment variables to child
worker.on('online',onOnline.bind(null, worker));
worker.on('message',onMessage.bind(null, worker));
worker.on('exit',onExit.bind(null, worker));
worker.workerType = workerType;
return worker;
// you can use worker.send() to send a message that
// will raise a message event in the child
}
function startWorker() {
console.log("Running Worker: %s %s", cluster.worker.id, process.env.WORKER_TYPE);
setTimeout(process.exit.bind(process,0), 5000); //close in 5 seconds
//you may want to load a specific module based on WORKER_TYPE
}
function onOnline(worker) {
console.log("Worker Online: %s %s", worker.id, worker.workerType);
//console.log(arguments);
}
function onMessage(worker, msg) {
if (msg.err) {
console.warn("Error From", worker.id, worker.workerType, msg.err);
} else {
console.log("Message From", worker.id, worker.workerType);
}
//console.log(arguments);
}
function onExit(worker, code, signal) {
console.log("Worker Exited: %s %s %s %s", worker.id, worker.workerType, code, signal);
if (env == 'dev') {
//for now just exit the whole thing (dev mode)
process.nextTick(function(){
process.exit(1);
});
} else {
//workers should simply keep working...
//fire off a new worker
createWorker(worker.workerType);
}
}
Related
Is it possible to perform a lookup of a Bluetooth device given its address in a Nodejs script?
There are a few packages out there, the main one being Noble. However, they all focus around scanning, and not looking up a known address (as far as i can tell anyway!).
What i want to achieve, is to look up a known address, to see if the device can be found.
Much like PyBluez does for Python:
bluetooth.lookup_name('CC:20:E8:8F:3A:1D', timeout=5)
In Python, this can find the device even if it is undiscoverable, unlike a typical inquiry scan would.
I had this same problem and just found the btwatch lib, but it isn't working for me on the latest raspbian. But the source is just calling l2ping and looking for a string that I'm guessing no longer prints on success, so the modified code below works instead, similar to the lookup_name method, once you have l2ping installed (I think npm bluetooth or pybluez has it)
var Spawn = require('child_process').spawn;
function detectMacAddress(macAddress, callback)
{
//var macAddress = '72:44:56:05:79:A0';
var ls = Spawn('l2ping', ['-c', '1', '-t', '5', macAddress]);
ls.stdout.on('data', function (data) {
console.log("Found device in Range! " + macAddress);
callback(true);
});
ls.on('close', function () {
console.log("Could not find: " + macAddress);
callback(false);
});
}
Or, a synchronous way,
var execSync = require('child_process').execSync;
function detectMacAddressSync(macAddress)
{
var cmd = 'l2ping -c 1 -t 5 ' + macAddress;
try
{
var output = execSync(cmd );
console.log("output : "+ output );
return true;
}
catch(e)
{
console.log("caught: " + e);
return false;
}
}
As far as I have understood the problem you want to connect to the device using address. Then, I would suggest using node-bluetooth-serial-port.
var btSerial = new (require('bluetooth-serialport')).BluetoothSerialPort();
btSerial.on('found', function(address, name) {
btSerial.findSerialPortChannel(address, function(channel) {
btSerial.connect(address, channel, function() {
console.log('connected');
btSerial.write(new Buffer('my data', 'utf-8'), function(err, bytesWritten) {
if (err) console.log(err);
});
btSerial.on('data', function(buffer) {
console.log(buffer.toString('utf-8'));
});
}, function () {
console.log('cannot connect');
});
// close the connection when you're ready
btSerial.close();
}, function() {
console.log('found nothing');
});
});
BluetoothSerialPort.findSerialPortChannel(address, callback[, errorCallback])
Checks if a device has a serial port service running and if it is found it passes the channel id to use for the RFCOMM connection.
callback(channel) - called when finished looking for a serial port on the device.
errorCallback - called the search finished but no serial port channel was found on the device. Connects to a remote bluetooth device.
bluetoothAddress - the address of the remote Bluetooth device.
channel - the channel to connect to.
[successCallback] - called when a connection has been established.
[errorCallback(err)] - called when the connection attempt results in an error. The parameter is an Error object.
I am trying to receive push messages from GCM. I simply followed the tutorial and registered the service worker as below:-
function urlB64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
var subscribeForPush = function() {
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
serviceWorkerRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey : urlB64ToUint8Array('<API-KEY>')
})
.then(function(subscription) {
console.log("Subscription for Push successful: ", subscription);
})
.catch(function(error) {
console.log("Subscription for Push failed", error);
});
});
};
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful with scope: ', registration.scope);
subscribeForPush();
}).catch(function(err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
});
}
Now, I get the device Id ("cw4jK8NhJgY:APA91bHr64E_kSdh7kN_VjcZRKulPf8KPLJLBjtnHI2qkYzx3-I9aUhunjzVcJjLtkHl9zvN8ys80gADK8tV8SueLX1R2jS0xgrf1Ur6cDw3jNjloUJp8PtWaIN-cEKXj69TZ9-D2Hiw")
from url:- "https://android.googleapis.com/gcm/send/cw4jK8NhJgY:APA91bHr64E_kSdh7kN_VjcZRKulPf8KPLJLBjtnHI2qkYzx3-I9aUhunjzVcJjLtkHl9zvN8ys80gADK8tV8SueLX1R2jS0xgrf1Ur6cDw3jNjloUJp8PtWaIN-cEKXj69TZ9-D2Hiw"
In my service worker file, I simply listen to push messages like:-
self.addEventListener('push', function(event) {
console.log(event)
});
I am able to send messages to gcm using terminal and get the message:-
{"multicast_id":4983340130324592129,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1483043226210433%cc9b4facf9fd7ecd"}]}
But I dont know why I dont see logs in push listener? I am stuck in this issue for more than 2 days. Can anyone please help me here? I am doing this in localhost.
You are not returning the pushManager subscribe
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
return serviceWorkerRegistration.pushManager.subscribe({
'userVisibleOnly': true
}).then(function(subscription) {
if (!subscription) {
// Set appropriate app states.
return;
}
console.log(subscription.endpoint);
}).catch(function (err) {
console.log('error in subcription .. '+ err);
});
})
Check my github project https://github.com/bvakiti/bvakiti.github.io/blob/master/app.js
Let me know if you need any details
I would like to add to bvakiti's solution by declaring
applicationServerKey: convertedVapidKey
in the pushManager subscribe. Most of the tutorials I found in the internet just uses bvakiti's method and most of the devs who follow that tutorial encountered issues in receiving the push notifications.
I was facing the same issue. I updated my Google Chrome version and it fixed the issue.
If you are sure your service worker is registered in the browser but your 'push' event is not getting triggered, you can debug all incoming push notifications to Google Chrome by doing the following:
Open chrome://gcm-internals
Start recording
Send a test push notification to the browser
Observe the logs
The server was getting a 201 on the push request and the browser threw no errors in the console log. However, I was having a decryption issue. The browser was receiving the push notification but failed to decrypt it: AES-GCM decryption failed.
Helpful Source: https://developers.google.com/web/fundamentals/push-notifications/common-issues-and-reporting-bugs
Strange issue I haven't really found documentation about. I think it may end up being a simple case of "you don't understand how the product works" and I'm hoping someone can fill the gap(s).
Here's what's going on... I have 3 separate apps which are socket.io servers. They're all listening on different ports. Each server is intended for a different specialized purpose. I'm building the application so that I can expand it in parts and only impact the individual isolated pieces I need to change/update.
This was working fine, until I realized that for each application running there's an extra socket connection per server. So if I have 3 apps, then I have 3 connections on each server.
The evidence of this is that if I add a console.log("Connected") to each server then connect a client, each server reports as many connections as there are servers. Hopefully this makes sense.
My goal, is I want 1 connection per server. It seems like the connections are each acting as a generic connection to all socket servers. My server listeners are set up like this :
io = require('socket.io').listen(26265) // can use up to 26485
My clients connect like this :
socket = new io('http://localhost:26265')
EDIT:
To add on to my original question so that you can see more code...
Full client code:
importJS('/js/pages/admin_base.js',function(){
AdminIO = new io('http://localhost:26266');
AdminIO.on('send_users',function(rows){
toggleLoad();
/*
if(typeof rows === 'object'){
rows = Array(rows);
}
*/
appendUsers(rows);
console.log(rows);
});
AdminIO.on('failed_users',function(){
toggleLoad();
dropInfo("Failed to retrieve userlist",{level: "error"});
});
AdminIO.on('test',function (q) {
console.log(q);
});
queryUsers(AdminIO);
});
The server code is pretty long... So the relevant pieces are :
var io = require('socket.io').listen(26266); // can use up to 26484
//.... imported additional modules and defined simple functions here
io.on('connection', function (socket) {
socket.on('restart_request', function(req){
var success = false
, session = JSON.parse(req.session)
, sessionID = session.sessionID;
checkSession(sessionID, function (ses) {
if (ses === false) { console.error('CheckSession failed: No session exists'); return; }
if (ses.user.uuid !== session.uuid) { console.error('CheckSession failed: UUID mismatched'); return; }
if (ses.user.role < conf['Permissions']['lm_restart']){ socket.emit('restart_fail','Insufficient permissions.'); return; }
if(process.platform === 'win32'){
executeCMD('START "" .\\windows\\scripts\\restart_lm.bat',function(err,res){
var errSent = false;
if(err){
console.error(err);
if(!errSent){ socket.emit('restart_fail','Restart failed'); }
errSent = true;
if(res === null){return;}
}
console.log(res);
socket.emit('restart_success','LM successfully restarted.');
});
}
else if(process.platform === 'linux'){
}
});
});
socket.on('get_users',function(req){
var success = false
, session = JSON.parse(req.session)
, opts = req.opts || null
, sessionID = session.sessionID
, col = opts.col || null
, where = opts.where || null
, range = opts.range || null
;
checkSession(sessionID, function (ses) {
if (!ses) { console.error('CheckSession failed: No session exists'); return; }
if (ses.user.uuid !== session.uuid) { console.error('CheckSession failed: UUID mismatched'); return; }
if (ses.user.role < conf['Permissions']['lm_user_query']){ socket.emit('userQuery_fail','Insufficient permissions.'); return; }
Query.users({col: col, where: where, range: range},function(err,res){
if(!err){socket.emit('send_users',res);}
else {socket.emit('failed_users',true);}
});
});
});
socket.on('test',function(q){
socket.emit('test',q);
});
});
Try removing the 'new' keyword from the io thing.
You shouldn't use 'new' there since it would make new instances every time you reload the page or a new client connects.
So, it should look like:
Server side:
var io = require('socket.io')(26265);
Client side:
var socket = io('http://localhost:26265');
I think this is what you were looking for.
I am trying to implement a feature where I can press on a button to delete some properties of my model.
My Model is:
Request:
status
shopper
I am using an event based structure:
This is the front end
a.requests-deny(href='#', data-id=request.id) Deny request
and this is my backend
var Request = require('../../models/Request');
var ShopperRequests = Backbone.View.extend({
el: '.shoppers-requests',
events: {
'click .requests-deny' : 'requestDeny'
},
requestDeny: function(e){
e.preventDefault();
var target = $(e.currentTarget);
var requestId = target.data('id');
console.log(requestId);
Request.findById(requestId, function(err, request) {
console.log(request);
if (err) {
return console.log('oh no! error', err);
} else {
request.status = 'pending';
request.shopper = '';
request.save(function(err) { // <-- save it back to the database
if (err) {
console.log('oh no! could not be saved in db', err);
} else {
console.log(request);
}
});
}
});
},
Looking at the console in the browser I see that first of all I can't use "require" because "it's not defined"
Uncaught ReferenceError: require is not defined(anonymous function) # shopper-f28ac0daf1d6a206b3172e4b9c670dd4.js:1
I was thinking of taking the requestId and just updating the values in the database but apparently this is not working.
Any idea if this could work or how else I could implement it?
You are not loading the RequireJs library in your backend. Thats why you are getting require is not defined.
If you are using Node, add it like this:
npm install requirejs
Or else, download it from here, and add it to your project with a script tag.
How can I fail a PULL to get retransmit from the pusher?
In the following example, if I uncomment the // throw ... to trigger an exception on every received message, all the PULL messages are failing, but when I put back the comment, all those messages are lost and not retransmitted by the pusher.
How can I make sure the pusher will retransmit the messages if the PULL method fail?
P.S. The following code is JavaScript in Meteor framework on top of nodejs, but it's not relevant to the problem as I suppose it's similar in every zmq implementations.
var zmq = Npm.require(modulePath + '/zmq');
var sock = zmq.socket('pull');
sock.identity = 'receiving' + process.pid;
sock.bind('tcp://172.17.4.25:5551', function(err) {
if (err) throw err
if (debug) console.log('Listening for ZMQ messages')
});
sock.on('message', Meteor.bindEnvironment(function(data) {
// throw { name: 'MessagePullFailed', message: 'Failing Pull message to check if ZMQ can recover from it' }
var jsondata = JSON.parse(data)
if (jsondata.cmd == 'upsert') {
jsondata['set']['utctime'] = new Date(jsondata['set']['utctime'])
Mon.upsert({_id: jsondata._id}, {'$set': jsondata['set']}, function(err) {
if (err) console.log(err)
})
}
}))