I am working on a live terminal in the browser over socket.io. And I encountered a problem.
My code:
child = require('child_process').spawn('cli opening command'),
//simple output to the client
child.stdout.on('data', function(data) {
io.emit('consoleOut', data);
});
//socket
io.on('connection', (socket) => {
socket.on('consoleInput', (msg) => {
//writing the message to the stdin stream
child.stdin.write(msg + '\n');
})
});
The Problem:
With this setup, the output is always "No such command '[user input]'..." only on the first input after the CLI was started it is working fine. And when I look at the output, I see that the first letter between the two quotes is an ASCII decimal 4 that equals to an end of transmission character.
Example (if I look at the string in the browser):
No such command '\u0004set verbose 5'
And the weird thing is when I write to the stream and hardcode it, the commands are perfectly fine and get executed like they should. But if then a user inputs his command, again every command is not working, even the first one.
child.stdin.write('set verbose 5\n');
child.stdin.write('set verbose 3\n');
I can verify that it is not the user input because when I change the socket on the consoleInput function into:
child.stdin.write('test' + msg + '\n');
I still get the same output (if for example the user inputs set verbose 5):
No such command '\u0004testset verbose 5'
(of course the command wouldn't work in the first place, but it's to show for the EOT chat)
My guess:
I get the EOT char only when I write to the buffer, and my string includes at least one \n.
Then everything until the last \n gets sliced out of the buffer, and there is then a EOT char left behind.
And It makes sense if this is true that I can input one command at the start that is working fine because there the whole buffer is empty and no EOT char is there.
Thanks, Julian ;)
Related
AndroidPhone---------Raspberry Pi ------------Arduino
(server) (server) (bluetooth)
(bluetooth)
Now i can send message(0or1) from Android to Raspberry Pi by app
and i want to send this message to Arduino
However, when i play this code, message is not sent by bluetooth.
I think (stdin.process.on) is need input by enter.
but i cant. please help me
if (req.payload.toString() === '0') {
console.log('0');
process.stdin.on('data', function(data) {
var buf1 = Buffer.from(data);
serial.write(buf1,fuction(err, bytesWritten) {
if (err) console.log(err);
});
};
serial.on('data',function(data){ console.log('Received'+data);
});
If your code was copied and pasted, you should fix that misspelled "fuction" on line 5 first.
Edit:
i want to know how to use stdin.on without console input
Sorry, I don't know much about messaging between devices but process.stdin is meant specifically to read standard input, which means either console input or messages piped to your node process from another process' stdout.
I have created a Redis cluster with 30 instances (15 masters/ 15 nodes). With python code i connected to these instances, i found the masters and then i wanted to add some keys to them.
def settomasters(port, host):
r = redis.Redis( host=host, port=port )
r.set("key"+port,"value")
Error:
redis.exceptions.ResponseError: MOVED 12539 127.0.0.1:30012
If i try to set key from redis-cli -c -p portofmyinstance sometimes i get a redirection message that tells where the keys stored.
I know that in case of get requests for example, a smart client is needed in order to redirect the requests to the correct node (the node that holds the key) otherwise a moved error occurs. Is it the same situation? I need to catch the redis.exceptions.ResponseError and try to set again?
while True:
try:
r.set("key","value")
break
except:
print "error"
pass
My first try was above code but without solution. The set operation never succeeds.
On the other hand below code in javascript does not throw an error and i cannot figure the reason:
var redis = require('redis-stream'),
client = new redis(30001, '127.0.0.1');
// Open stream
var stream = client.stream();
// Example of setting 200 records
for(var record = 0; record <200; record++) {
var command = ['set', 'qwerty' + record, 'QWERTYUIOP'];
stream.redis.write( redis.parse(command) );
}
stream.on('close', function () {
console.log('Completed!');
});
// Close the stream after batch insert
stream.end();
Any help will be appreciated, thanks.
with a redis cluster you can use the normal redis client only if you "find for the certain key the slot that belongs and then the slots that each master serves. With this information i can set keys to the correct node without moved redirection errors." as #Antonis said. Otherwise you need http://redis-py-cluster.readthedocs.io/en/master/
I am trying to make a program in Node.JS that will display some text, using console.log("");, then wait for the user to input some commands. First of all, I want to run this through the Linux Terminal on Cloud9 IDE, which does not pause long enough to input anything. Second of all, I want it to be like its own little command line. (I mean respond to certain case-sensitive commands, and ignore anything else.) Can anyone help with this?
Check out prompt. https://www.npmjs.com/package/prompt It works like:
var prompt = require('prompt');
prompt.start();
prompt.get(['hello'], function (err, result) {
console.log('you typed ' + result.hello);
});
Will do:
$ nodejs prompt.js
prompt: hello: world
you typed world
Happy coding ^^
Currently I'm using SSH2 and node.js to monitor disk space and partitions over remote server. And printing output to console. But the output is in string format so I couldn't store free space / total space value in any variable.
Current I'm running df -k command using con.exec in node.js(ssh2) to run command over remote servers using credentials.
So How would it would be possible(store disk space in variable).
My Final task is to check disk space over remote server and generate alert if it is < 25%.
And also for HTML part I'm using AngularJs. So I've to give a button over web page to force check and for generating alert for users.
I've added the output format I'm receiving over console(both) below
Use df -h | grep sd to select only the row of the HDD's main partition.
After that, in data content of result array (see your picture, first item of array "data":"RESULT") change the sequence of space to one space. For example after Filesystem in your uploaded picture there are 4 spaces, replace them with one space.
In the final string you sill have a result like this: /dev/sda1 609G 202G 376G 35% /
Now, you should split this string whit space char. Resulting in the array:
item[0] is Filesystem
item[1] is total space
item[2] is used space
item[3] is available space
item[4] is used space in percent form
item[5] is mounted on path
Very very important note: I suggest you do not use this methodology, because it is NOT secure (look at your picture).
Anyone can find it by tracing with a firebug!
Try this ,
if you are using linux system there is command "df -h | grep sd" to find out disk space i am sure there must be command for windows also
"child_process" module in js helps to run system commands . to find disk space details use following code .
let command = `df -h | grep sd`;
child_process.exec(command, (err, stdout, stdin) => {
if (err) {
console.log("Err", err)
}
console.log("Out", stdout.split(/[ ,]+/));
});
I have this small piece of code. I run it, and then connect with a Telnet client.
var net = require('net');
//create server
var server = net.createServer(function (conn) {
console.log('New connection!')
//Message to the one who connects.
conn.write (
'\n > Welcome to NODE-CHAT!'
+ '\n > ' + count + ' other people are connected at this time.'
+ '\n > Please write your name and press Enter: '
);
//When a connected user writes...
conn.on('data', function (data) {
console.log(data);
});
conn.setEncoding('utf8');
});
//Listen
server.listen(3000, function () {
console.log('Server listening on *:3000');
})
When connected i get the Welcome messages as expected... Then if i write something in the telnet client, it will immediately trigger the conn.on listener... Lets say i write "hi you" the output in the console will be:
h
i
y
o
u
I would like this messages to sent when it is "finished" instead whenever i type character. I guess i could store the data from the conn.on trigger in a string, and output this string when the '\n' character is typed.
But I'm wondering if this is the right way to do it. Is there a way to change what trigger the conn.on? Maybe so it will only trigger (that is output in this case... ) on certain characters?... namely the \n char.
TCP is a stream of data so you should not make any assumptions about how much data you will receive by calling .read() or when listening for data events.
If your input is newline delimited, then you will have to buffer until you see a newline. There could also be multiple newlines in one chunk passed to your data event handlers too.
I don't see any problems in your code. The behavior you describe is related to the Telnet client that sends every keystroke, it does not wait for you to hit enter. If you are on Linux try sending data with wget o open a browser and type
http://localhost:3000/hiyou
and see if you get a complete string instead of one character.