Node , SSh2 Server waiting for input - javascript

I am currently building a Web based SSH client. I am using node and SSH2 module to connect to Linux machine . The issue is trying to identify when the server is waiting for a response from the client say "sudo" .
this.onWsMessage = function(packet) {
log('Message Received from ');
if (cmd != '') {
log('----------------------------------------->' + cmd);
source[this.getId()].sshStream.write(cmd + '\n');
}
};
var client = clients[cid];
sshClient
.on('ready', function() {
console.log('CONNECTED');
sshClient.shell({pty: true}, function(err, stream) {
_shellHandler(err, stream, client);
});
})
.on('error', function(err) {
console.log('ERROR', err);
})
.connect(serverInfo);
}
function _shellHandler(err, stream, client) {
source[client.getId()].sshStream = stream;
stream
.on('close', function() {
log('ssh connection close');
//sshClient.end();
this._client.end();
})
.on('data', function(data) {
console.log(stream);
var msg = data.toString().replace(msgPattern, '');
this.sendUTF(msg, 'ssh');
}.bind(client));
}
I have been going through the documentation and i was unable to identify any event that trigger as a result.

There is no easy way to do this. Basically you have to either buffer stream output and continually search that buffer for expected (sudo) prompts or use a module like streamsearch to search the stream for a particular string without explicitly buffering and continual searching.

Related

Websocket memory leak node.js. Event emitters?

I am getting the event emitter leak after using my code 10 times essentially. I understand the default of event emitter auto sending out a warning in the console. My question is what in this code is directly creating the event listeners? Is it poor coding on my part or is it just how the websockets are stacked onto each other?
I'll explain the code a bit. I have one websocket within another and I figured it would serve the data to a web page essentially flowing from Twitch to a localhost site. However, if I use the keywords more than 10 times, I get the error. I do not understand enough about WebSockets to really understand why my code creates a new listener with each msg.text received so anyone with a bit more understanding please help!
I believe me issue to be similar to this though I am having a hard time conceptualizing my own code here
const { paintballShot } = require('./JavaScript/paintballGunFire');
const { readPin } = require('./JavaScript/readPin');
const ws = require('ws');
const express = require('express');
const app = express();
//CONNECT TO TWITCH
let client = new ChatClient({
connection: {
type: "websocket",
secure: true,
}
});
//connected?
client.on("ready", () => console.log("Successfully connected to chat"));
client.on("close", (error) => {
if (error != null) {
console.error("Client closed due to error", error);
}
});
//create headless websocket
const wsServer = new ws.Server({ noServer: true });
wsServer.on('connection', function connection(socket) {
//call other websocket connected to Twitch from inside the new websocket
client.on("PRIVMSG", (msg, error) => {
if (msg.messageText === "right") {
socket.send(JSON.stringify(`${msg.displayName}: ${msg.messageText}`));
}
if (msg.messageText === "left") {
socket.send(JSON.stringify(`${msg.displayName}: ${msg.messageText}`));
}
if (msg.messageText === "fire") {
socket.send(JSON.stringify(`${msg.displayName}: ${msg.messageText}`));
paintballShot();
}
if (msg.messageText === "pin") {
readPin();
}
process.on('uncaughtException', function (err) {
console.log(err);
});
});
client.connect();
client.join("channel");
socket.on('message', message => console.log(message));
});
// `server` is a vanilla Node.js HTTP server
const server = app.listen(3000);
server.on('upgrade', (request, socket, head) => {
wsServer.handleUpgrade(request, socket, head, socket => {
wsServer.emit('connection', socket, request);
});
});
process.on('uncaughtException', function (err) {
console.log(err);
});
To wrap this up, the library I am using (Dank TwitchIRC) does have a connection rate limiter that seems to work if you add it to your chat client in the beginning. If I set it low enough, depending on the messages received from Twitch, it will end connections just as fast, meaning no memory leak.

Writing and reading data between two nodejs servers using node serial port

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

webRTC losses stream when a phone call is answered

In the scenario where two users are connected in a video call, one of them gets a phone call and he answers the call. this blocks the ongoing webRTC stream and the call session ends.
So is there a way we can maintain both the steam as well as the call session and resume the video call once the person return on our application.
I am using QuickBlox js-Sdk to make calls.
below is the code snippet attached to initiate the call.
var userCredentials = {
userId: 'XXXXXX',
password: "XXXXXXX"
};
QB.chat.connect(userCredentials, function (error, contactList) {
var calleesIds = [XXXXX];
var sessionType = QB.webrtc.CallType.VIDEO;
var session = QB.webrtc.createNewSession(calleesIds, sessionType);
this.userAuthService.markBusy(XXXXX).subscribe(data => data);
var mediaParams = {
audio: true,
video: true,
options: {
muted: true,
mirror: true
},
elemId: "selfStream"
};
session.getUserMedia(mediaParams, function (err, stream) {
if (err) {
console.log('getUserMedia err', err);
} else {
console.log('getUserMedia succ', stream);
// make call
var extension = {};
session.call(extension, function (error) {
console.log('call error: ', error);
});
}
});
});
and on the other side to receive the call.
QB.webrtc.onCallListener = function (session, extension) {
session.getUserMedia(self.getMediaParams('selfStream'), function (err, stream) {
if (err) {
console.log('getUserMedia err', err);
} else {
self.callSession.accept(self.callExt);
}
});
};
I have seen the same issue in some other webApps as well, Is there a fix/workaround for this problem, thanks in advance.
Get around this by adding an event on the remote user's stream. If the stream is null it'll start checking for the stream every second for 2 mins if stream is not restored back in 2 mins the call will be disconnected. else I'll use the restored stream and remove the timeInterval to check every second.

Parsing Xml large file shutdown the server nodejs

I have written code in node js, I get XML data in a stream from the server, then parse it. locally it works fine, but when I deploy on the server, it shut down the server node.
it takes 100% CPU usage. Is there any way to minimum use CPU usage?
Any expert opinion
const axios = require('axios'),
node_xml_stream = require('node-xml-stream'),
httpAdapter = require('axios/lib/adapters/http');
let response;
try {
sails.log.info('Before http stream request');
response = await axios.get(process.env.SRO_FEED_URL, {
responseType: 'stream',
adapter: httpAdapter
});
} catch (error) {
sails.log.error('http request error ', error);
}
const stream = response.data;
sails.log.info('After the feed response');
parser = new node_xml_stream(),
stream.pipe(parser);
parser.on('opentag',
function(name, attrs) {
if (name === 'job') {
// let attr = attrs;
}
t_name = name; })
parser.on('text', function(text) {
if (t_name === 'id') {
id = text;
}
if (t_name === 'company') {
company = text;
}
});
code locally working fine, but when I deploy its crash the server.
I'm having a tough time finding a node package that can parse large XML files that are 1G+ in size.

Node child_process and twitch api

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.

Categories