I am facing same issue as mentioned in this question
Node.js TCP socket waits seconds before polling? (net.createServer)
I tried the answer marked as correct here but not able to understand how it is helpful. By adding that line "sock.write(data);" inside the "sock.on('data', function(data)" event, my "TELLER" goes into infinite loop.
Can anyone please help me understand what I am doing wrong?
Here is my code,
server.on('connection', function (sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sock.setNoDelay(true);
sock.on('error', function (err) {
console.log("ERROR : " + err.toString());
});
sock.on('data', function (data) {
console.log(moment().format("HH:mm:ss") + ' DATA : ' + sock.remoteAddress + ': ' + data);
data = data.toString().trim();
if (data.indexOf("MY_DATA_DELIMITER") > -1) {
console.log(moment().format("HH:mm:ss") + ' sending a command');
sock.write("MY_COMMAND");
////////// I get a response of this write after 5 seconds
}
});
sock.on('close', function (data) {
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
});
sock.on('end', function () {
console.log('ENDED : ' + sock.remoteAddress + ' ' + sock.remotePort);
});
});
In the data event, when I receive a string containing MY_DATA_DELIMITER, I send a COMMAND (just a string not more than 50 characters). The client, as a response to this COMMAND, sends a REPLY. I get this REPLY exactly after 5 seconds.
Turned out to be the way it is handled in CLIENT program. I do not have control over the CLIENT program hence it took much time to debug & figure out what is causing the delay.
The CLIENT expects a line ending with each message as the delimiter.
Though the example code I shared here uses line ending with message, I missed sending that in my actual code.
Hence the CLIENT kept waiting to detect end of message & this waiting took 5 seconds.
Now when I send the line ending character with each message, it is working without any delay.
Thank you for your time to look at it.
Related
I am currently working with Twilio and NodeJS.
I am building sort of a dialer that loops over an object and makes outbound calls.
I would like to find a way to limit the number of ongoing calls to a certain number e.g. 5 calls at a time.
Ideas so far,
store a status variable on my object (list of people to call) and before going to the next iteration count the number of ongoing call if <5, continue if >5 wait x secs.
before each iteration, make a request to Twilio to know the number of ongoing call on Twilio side and then continue if
Here is my code:
function loopSession() {
logger.info('Starting looping over sessions')
async.forEach(Object.keys(sessions.returnAllSessions()), function (sessionKey, callback) {
let session = sessions.returnSingleSession(sessionKey);
logger.debug('Processing :' + session.user.mobileNo + ' started');
// CONDITION TO HAVE LESS THAN 5 ONGOING CALLS
callClient(session.user.mobileNo); // should be async?
logger.debug('Processing :' + session.user.mobileNo + ' done')
callback();
}, function (err) {
if (err) {
logger.debug(err);
} else {
logger.info('Iterating over session done');
}
});
}
Thanks for your help!
I'm trying to pipe grep results into nodejs script. I've found, that I should receive data from process.stdin.
Also I've found several ways to work with stdin. But they are different and I can't find all information about it. I know four ways (first 3 start with var data = ""):
1) Most popular in search results
process.stdin.resume();
process.stdin.setEncoding( 'utf8' );
process.stdin.on('data', function(chunk) { data += chunk; });
process.stdin.on('end', function() { console.log('data: ' + data); });
2) Looks like the first one, but with unknown function process.openStdin()
var stdin = process.openStdin();
stdin.on('data', function(chunk) { data += chunk; });
stdin.on('end', function() { console.log('data: ' + data); });
3) In the documentation I've read that calling stdin.resume() changes stdin to 'old type'. So if we didn't called 'resume' - we can use 'readable' event
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function() { data += process.stdin.read(); });
process.stdin.on('end', function() { console.log('data: ' + data); });
4) Use module readline. It is very usefull as long as grep results are in mutiple lines and there I don't need to split received data by myself. But for a long time i couldn't understand why all information is piped to stdout directly. Then i i've found that we can pass empty object instead of process.stdout while creating interface and data wouldn't piped to output.
var readline = require('readline'),
//rl = readline.createInterface(process.stdin, process.stdout);
rl = readline.createInterface(process.stdin, {});
rl.on('line', function(data) { console.log('line: ' + data); });
5) My own variant. Use another module 'split' - it allows to read from stream and devide data into chuks by specified symbol (\r?\n by default). I used it to work with socket and as soon as stdin is also readable stream - we can use it here.
var split = require('split');
process.stdin.setEncoding('utf8');
process.stdin.pipe(split()).on('data', function(data) { console.log('line: ' + data); });
My question is "What is process.openStdin();????"
I've searched every page in google, but didn't found any documentation on this function!
Also while searching I've discovered, that official documentation for nodejs is ugly - not mentioned since which version methods are available, no detailed description on many objects/methods, no user comments. And this method (openStdin) - exists and works, but nowhere discribed! WTF???
While writing the question I've found the answer :)
It is in source code of nodejs:
process.openStdin = function() {
process.stdin.resume();
return process.stdin;
};
But I wonder, why is it not described in documentation? If it is a function for private use only, why is it used by many people, who wrote about working with stdin?
There were already a few questions here about node.js executing commands and outputting the data, but I still can't get this working. What I want is that using node.js I want to execute a python script that runs for a long time and produces some intermediate outputs. I want to stream these outputs to the client as soon as they are produced. I have tried the following, but what I get is that I get the whole output only once the command has finished. How can I make it pass on the data into the socket in real time? Thanks.
function run_cmd(cmd, args) {
var spawn = require('child_process').spawn,
child = spawn(cmd, args);
return child;
}
io.sockets.on('connection', function (socket) {
var foo = new run_cmd('python', ['test.py']);
foo.stdout.setEncoding('utf-8');
foo.stdout.on('data', function(data) {
console.log('sending data');
io.sockets.emit('terminal', {output: data});;
});
);
all your node.js code is okay.your code sends data only once because your code gets data only once.
The point is puts or print commands are not enough to trigger foo.stdout.on
try adding '$stdout.flush' at the point you want to send chunk in ruby code.
You need to order explicitly to output data.
here is my test code.
js
var spawn = require('child_process').spawn;
var cmd = spawn('ruby', ['testRuby.rb']);
var counter = 0;
cmd.stdout.on('data', function(data) {
counter ++;
console.log('stdout: ' + data);
});
cmd.stderr.on('data', function(data) {
console.log('stderr: ' + data);
});
cmd.on('exit', function(code) {
console.log('exit code: ' + code);
console.log(counter);
});
testRuby.rb
def execute_each_sec(sleep_sec)
yield
sleep sleep_sec
end
5.times do
execute_each_sec(1) do ||
puts "CurrentTime:#{Time.now}"
$stdout.flush
end
end
as you can see I'm calling $stdout.flush to output data explicitly in testRuby.rb.
if I remove that,node.js won't get anything until execution of testRuby.rb's finished.
edited
lol my bad. I used ruby instead of python.
in the case of python, use sys.stdout.flush() like svkk says
Edit:
In python you can also use -u flag to force it to flush after each print.
Require the modules
var net = require("net");
Store the users and the connections number
var count = 0,
users = {};
Creates the server
var server = net.createServer(function (conn){
Stores the current nickname and set the utf8 encoding
var nickname;
conn.setEncoding('utf8');
Shows a message on the shell when you stablish a connection
conn.write(' > welcome to \033[92mnode-chat\033[39m!'
+ '\n > ' + count + ' other people are connected at this time.'
+ '\n > please write your name and press enter: ');
The number of connections++
count++;
When recives data it checks if there is a user in the storage with that name shows a message and return. Else shows a welcome message. Otherwise, if you input a message or any data (after have registered your nickname) shows it on the shell.
conn.on('data', function (data){
data = data.replace('\r\n', '');
if(!nickname) {
if(users[data]) {
conn.write('\033[93m > nickname already in use. Try again:\033[39m ');
return;
} else {
nickname = data;
users[nickname] = conn;
for(var i in users) {
users[i].write('\033[90m > ' + nickname + ' joined the room\033[39m\n');
}
}
} else {
for(var i in users) {
if(i != nickname) {
users[i].write('\033[96m > ' + nickname + ':\033[39m ' + data + '\n');
}
}
}
});
When you close or end the connection deletes your nickname from the storage, number of connections-- and shows a message.
conn.on('close', function(){
count--;
delete users[nickname];
conn.write('\033[90 > ' + nickname + ' left the room\033[39m\n');
});
});
Server on port 3000
server.listen(3000, function (){
console.log('\033[96m server listening on *:3000\033[39m');
});
I have a bug in my chat. I stablish two telnet connections using de shell. But when I close one the other one close two, and shows me a error message. What is wrong with my code?
You're trying to write to a closed connection, which will fail since writing to a closed Writable stream throws an error.
conn.on('close', function(){
count--;
delete users[nickname];
conn.write('\033[90 > ' + nickname + ' left the room\033[39m\n');
});
What you want is to broadcast the message to all other users either using Object.keys or a for-in loop.
conn.on('close', function() {
count --;
delete users[nickname];
Object.keys(users).forEach(function (user) {
users[user].write(nickname + ' left the room');
});
}
You also don't need a separate count variable to track connected users.
Object.keys(users).length;
But when I close one the other one close two, and shows me a error
message
It is because you're not listening for an error event and, by default, an EventEmitter throws an error if an error occurs and no error listener is attached.
conn.on('error', console.log);
I'm writing a simple online conversion tool using FFMPEG and Node.js. I'm trying to figure out how to parse each line of the conversion output received from FFMPEG and only display pertinent results client side in the browser. In my case I want the encoding time counter that FFMPEG spits out on the command line.
My function thus far is:
function metric(ffmpeg, res) {
ffmpeg.stdout.on('data', function(data) {
res.writeHead(200, {'content-type': 'text/html'});
res.write('received upload:\n\n');
console.log(data);
});
ffmpeg.stderr.on('data', function (data) {
var temp += data.toString();
var lines = temp.split('\n');
//for debugging purposes
for(var i = 0;i<lines.length;i++) {
console.log('this is line: ' + i + '----' + lines[i]);
}
res.write(lines);
});
ffmpeg.on('exit', function (code) {
console.log('child process exited with code ' + code);
res.end();
});
}
What this ends up returning is multiple arrays, each of which includes the data from the previous array as well as the next data chunk. For example, the function returns array 1:{0=>A, 1=>B}, array 2:{0=>A, 1=>B, 2=>C}, array 3:{0=>A, 1=>B, 2=>C, 3=>D}, and so on.
I'm quite new to Node so I'm probably missing something simple. Any guidance would be much appreciated!
This should do the job:
var buff = new Buffer(data);
console.log(buff.toString('utf8'));
For more information on buffers, here is a link to the doc: http://nodejs.org/docs/v0.4.2/api/buffers.html