how to concatenate buffer.toString() output with another string in Node.js - string

I'm using a simple socket script to establish an rcon connection to my Battlefield heroes server. I need to grab the seed from the returned data then concatenate it with the password to use in creating the login hash I need. But the strings won't concatenate with the normal string methods. If I output the strings separately they display fine, but they simply won't combine so I can hash them.
var net = require('net');
var crypto = require('crypto');
var md5sum = crypto.createHash('md5');
var HOST = '<ip address>', PORT = <port>,
PASSWORD = '<password>';
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
});
client.on('data', function(data) {
console.log(data.toString());
response = data.toString();
if (data.toString().slice(0,10) == "### Digest") {
var seed = response.slice(17);
auth = seed.concat(PASSWORD);
console.log('auth: '+auth);
hash = require('crypto').createHash('md5').update(auth).digest("hex");
console.log(hash);
//client.write('login '+hash+' \n');
}
//client.destroy();
});
client.on('close', function() {
//do something on close
});
client.on('error', function(err) {
console.log(err);
});

I found a solution that works for me. Not sure if I'm over doing it but I decided to pass both strings to new buffers. Then I passed them into an array to combine them. (shrug) I think it'll do. Any better solutions?
var net = require('net');
var crypto = require('crypto');
var md5sum = crypto.createHash('md5');
var HOST = '<ip address>', PORT = <port>,
PASSWORD = '<password>';
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
});
client.on('data', function(data) {
console.log(data.toString());
response = data.toString();
if (data.toString().slice(0,10) == "### Digest") {
var a = new Buffer(response.slice(17));
var b = new Buffer(PASSWORD);
var auth = new Array();
auth += a.toString().replace(/\n/g,'');
auth += b.toString();
hash = require('crypto').createHash('md5').update(auth).digest("hex");
client.write('login '+hash+' \n');
}
//client.destroy();
});
client.on('close', function() {
//do something on close
});
client.on('error', function(err) {
console.log(err);
});

Related

Send message synchronously with Nodejs Websocket

My app has three modules:
WebSocket Module: resides on the remote server (internet) and it acts as a Websocket
server that entertain the connection between Client Module and
Webhook module.
Webhook Module: resides on the remote server (internet) and it acts as
a webhook to answer the HTTP post request from the user. It is connected to Websocket Module via websocket as well.
Client Module: resides on my local machine and it is connected to
the
Webhook model via websocket. This client responsible to get query
from my local backend.
When a user call Webhook Module through HTTP Post request, Webhook module initiate a connection to WebSocket module via websocket. Then, the WebSocket module initiate the connection to Client module and response back with the necessary information. Actually I have to do this to eliminate the HTTP tunnel that is blocked in my company.
The problem is, when I open two browser windows to perform the HTTP Post request at the same time with different parameter, for example, param "A", I would expect to get return "A", with param "B", I expect to get "B" not "A". But There is something wrong with my codes/design. If I executed at the same time, I throw "A" then I got "B" which is wrong. How do I overcome this.
This is a simple diagram to illustrate it.
WebSocket Module:
'use strict'
//This is WebSocket Server
const clients = {};
const SocketIO = require('socket.io');
const express = require('express');
const http = require('http');
const app = express();
const server = http.createServer(app);
const ws = SocketIO(server);
const port = 3000;
var clientid;
ws.on('connection', (client) => {
clients[client.id] = client;
console.log('new connection', client.id);
clientid = client.id;
client.emit('message', { message: 'welc' })
client.on('disconnect', () => {
delete clients[client.id];
console.log('Client ' + client.id + ' disconnected. Deleted');
});
client.on('WH', function (from, msg) {
console.log('Message from Webhook', from, ' : ', msg);
client.broadcast.emit('message', { message: msg });
//console.log('send to: ' + clientid);
//ws.to(clientid).emit('hey', { message: msg });
//client.emit('message', { message: msg })
});
client.on('CL', function (from, msg) {
console.log('Message from Client', from, ' : ', msg);
client.broadcast.emit('message', 'me', msg);
//ws.to(client.id).emit('message', 'me', msg);
//client.emit('message', 'me', msg);
});
});
server.listen(process.env.PORT || port);
console.log('WebSocket Server is running on port ' + port);
Webhook Module
'use strict'
//This is WebHook Server
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const http = require('http');
const io = require('socket.io-client');
const app = express()
app.use(bodyParser.json())
const clients = {};
const SocketIO = require('socket.io');
const server = http.createServer(app);
const ws = SocketIO(server);
const port = 5000;
let Res;
let httpreq = false;
let nctid;
let ts;
const socket = io.connect('http://localhost:3000', {reconnect: true});
// Add a connect listener
socket.on('connect', function() {
console.log('Connected to WebSocket server!');
});
socket.on('message', function(from, msg) {
//console.log('Message from ', from, ' : ', msg);
console.log('nctid: ' + nctid + ', ts: ' + ts);
//Get the message from Client
if (httpreq) {
Res.send({
replies: [{
type: 'text',
content: msg,
}],
conversation: {
memory: {
key: msg
}
}
})
httpreq = false;
}
});
app.listen(process.env.PORT || port, () => {
console.log('Webhook server is running on port ' + port);
})
app.post('/', (req, res) => {
//console.log(req.body)
let query = req.body.nlp.entities.query[0].value;
nctid = req.body.nlp.entities.nctid[0].value;
ts = Math.floor(Date.now() / 1000);
console.log("query: " + query + '|' + nctid + '|' + ts);
//Send message to WebSocket server with parameter query and NCTID
socket.emit('WH', 'me', query + '|' + nctid);
Res = res;
httpreq = true;
})
app.post('/errors', (req, res) => {
console.log(req.body);
res.send();
})
Client Module
'use strict'
//This is client app running on client premise
const request = require('request');
const parser = require('xml2json');
const io = require('socket.io-client');
const socket = io.connect('http://localhost:3000', {reconnect: true});
// Add a connect listener
socket.on('connect', function(socket) {
console.log('Connected to WebSocket server!');
});
socket.on('message', function(from, msg) {
//console.log('MSG', from, ' : ', msg);
console.log(from);
let param = from.message.split('|');
let query = param[0];
let nctid = param[1];
if (typeof nctid != 'undefined') {
getNCTID(nctid, function(returnValue) {
//console.log(returnValue);
try {
let json = parser.toJson(returnValue);
json = JSON.parse(json);
if (query == 'title')
socket.emit('CL', 'me', 'Title is ' + json.clinical_study.brief_title);
else
socket.emit('CL', 'me', 'Status is ' + json.clinical_study.overall_status);
} catch (e) {
console.log(e);
socket.emit('CL', 'me', 'No NCTID ' + nctid);
}
});
}
});
function getNCTID(nctid, callback) {
let url = "https://clinicaltrials.gov/ct2/show/" + nctid + "?displayxml=true";
let options = {
url: url,
method: 'GET'
}
//console.log(options);
let requestWithEncoding = function(options, callback) {
let req = request.get(options);
req.on('response', function(res) {
let chunks = [];
res.on('data', function(chunk) {
chunks.push(chunk);
});
res.on('end', function() {
let buffer = Buffer.concat(chunks);
let encoding = res.headers['content-encoding'];
if (encoding == 'gzip') {
zlib.gunzip(buffer, function(err, decoded) {
callback(err, decoded && decoded.toString());
});
} else if (encoding == 'deflate') {
zlib.inflate(buffer, function(err, decoded) {
callback(err, decoded && decoded.toString());
})
} else {
callback(null, buffer.toString());
}
});
});
req.on('error', function(err) {
callback(err);
});
}
requestWithEncoding(options, function(err, data) {
if (err) {
console.log('err:' + err);
callback('error');
} else
//console.log(data);
callback(data);
})
}

SFTP Server for reading directory using node js

I have created a node based SSH2 SFTP Server and Client. My objective is to read directory structure of SFTP Server. Suppose I have an SFTP Server containing folder temp, I want to read files inside the temp directory. I am using ssh2 npm module for creating SFTP Server and Client. It is making connection to SFTP Server but not listing the directory
Below is the code
CLIENT SIDE SFTP
var Client = require('ssh2').Client;
var connSettings = {
host: 'localhost',
port: 22,
username:'ankit',
password:'shruti',
method:'password'
// You can use a key file too, read the ssh2 documentation
};
var conn = new Client();
conn.on('ready', function() {
console.log("connected to sftp server")
conn.sftp(function(err, sftp) {
if (err)
throw err;
sftp.readdir('',function(err,list)
{
console.log('Inside read')
if(err)
{
console.log(err);
throw err;
}
console.log('showing directory listing')
console.log(list);
conn.end();
})
/**
var moveFrom = "/remote/file/path/file.txt";
var moveTo = __dirname+'file1.txt';
sftp.fastGet(moveFrom, moveTo , {}, function(downloadError){
if(downloadError) throw downloadError;
console.log("Succesfully uploaded");
});
*/
})
}).connect(connSettings);
SERVER SIDE SFTP :
var constants = require('constants');
var fs = require('fs');
var ssh2 = require('ssh2');
var OPEN_MODE = ssh2.SFTP_OPEN_MODE;
var STATUS_CODE = ssh2.SFTP_STATUS_CODE;
var srv = new ssh2.Server({
hostKeys: [fs.readFileSync(__dirname+'/key/id_rsa')],debug:console.log
}, function(client) {
console.log('Client connected!');
client.on('authentication', function(ctx) {
if (ctx.method === 'password'
// Note: Don't do this in production code, see
// https://www.brendanlong.com/timing-attacks-and-usernames.html
// In node v6.0.0+, you can use `crypto.timingSafeEqual()` to safely
// compare two values.
&& ctx.username === 'ankit'
&& ctx.password === 'shruti')
ctx.accept();
else
ctx.reject();
}).on('ready', function() {
console.log('Client authenticated!');
});
client.on('session',function(accept,reject)
{
console.log("Client asking for session");
var session = accept();
var handleCount = 0;
var names=[]
session.on('sftp',function(accept,reject)
{
console.log('Client sftp connection')
var sftpStream = accept();
sftpStream.on('OPENDIR',function(reqID,path)
{
var handle = new Buffer(4);
handle.writeUInt32BE(handleCount++, 0, true);
sftpStream.handle(reqID,handle);
console.log(handle);
console.log('Opening Read Directory for --'+path);
console.log(reqID);
console.log(path);
}).on('READDIR',function(reqID,handle)
{
console.log('Read request')
console.log(reqID);
if(handle.length!==4)
return sftpStream.status(reqID, STATUS_CODE.FAILURE,'There was failure')
sftpStream.status(reqID, STATUS_CODE.OK,'Everything ok')
sftpStream.name(reqID,names);
})
})
})
}).listen(0, '127.0.0.1', function() {
console.log('Listening on port ' + this.address().port);
});
srv.listen(22)
The client will send multiple READDIR requests. On the first request, you should send the file listing, on the second you should send an EOF status, to tell the client the listing has finished.
An example would be:
let listSent = false;
let names = [];
sftpStream.on('OPENDIR', function (reqID, path) {
listSent = false;
sftpStream.handle(new Buffer());
});
sftpStream.on('READDIR', function (reqID, handle) {
if (listSent) {
sftpStream.status(reqID, STATUS_CODE.EOF);
return;
}
sftpStream.name(reqID, names);
listSent = true;
});

Nodejs - data transfer between server and client

I was given a task to send JSON string from client to server and from server to client, whenever there is a new record found to send.
I decided to build TCP connection(suggest me if there is any other better way in Node.js) between server and client to transfer data.
The problem is, I was supposed to use a delimiter to separate JSON strings one from another. I am afraid what if the json string contains the delimiter string inside the object. I am looking for a better way to separate two JSON strings.
Below is my code. Please help me.
Client
var net = require('net')
, client = new net.Socket();
var chunk = ''
, dlim_index = -1
, delimit = '~~';
client.connect(config.Port, config.IpAddress, function () {
console.log('Server Connected');
client.write('CLIENTID:' + process.argv[2]);
client.write(delimit);
});
client.on('data', function (data) {
var recvData = data.toString().trim();
chunk += recvData;
dlim_index = chunk.indexOf(recvData);
console.log(data);
while (dlim_index > -1) {
var useData = chunk.substring(0, dlim_index);
if (useData == 'SUCCESS') {
controller.listenOutQueue(function (dataToSend) {
var object = JSON.parse(dataToSend);
client.write(dataToSend);
client.write(delimit);
});
}
else {
var record = JSON.parse(useData);
controller.insertIntoQueue(record, function (status) {
});
}
chunk = chunk.substring(dlim_index + 2);
dlim_index = chunk.indexOf(delimit);
}
});
client.on('close', function () {
console.log('Connection closed');
});
client.setTimeout(50000, function () {
//client.destroy();
});
Server
var net = require('net')
, server = net.createServer()
, delimit = '~~'
, clients = [];
controller.listenOutQueue(function (dataToSend) {
client.write(dataToSend);
client.write(delimit);
});
server.on('connection', function (socket) {
var chunk = '';
var dlim_index = -1;
socket.on('data', function (data) {
var recvData = data.toString().trim();
chunk += recvData;
dlim_index = chunk.indexOf(delimit);
while (dlim_index > -1) {
var useData = chunk.substring(0, dlim_index);
if (useData.substring(0, 9) == 'CLIENTID:') {
socket.clientid = useData.replace('CLIENTID:', '');
console.log('Client Id: ' + socket.clientid);
clients.push(socket);
var successMessage = "SUCCESS";
socket.write(successMessage);
socket.write(delimit);
}
else {
controller.insertIntoQueue(JSON.parse(useData), function (status) {
});
}
chunk = chunk.substring(dlim_index + 2);
dlim_index = chunk.indexOf(delimit);
}
});
socket.on('end', function () {
console.log('Connection Closed (' + socket.clientid + ')');
});
socket.on('error', function (err) {
console.log('SOCKET ERROR:', err);
});
});
server.listen(config.Port, config.IpAddress);

Service multiple connection on NodeJS webserver

I have a web server running using Node.js with express and socket.io It displays real-time temperature information and allows for real-time control of some basic hardware controllers.
Each time I connect to the server from a different client, a new instance of the content is delivered as opposed to delivering the last configured instance or state.
Things work fine when just one client is used, but I need to be able to monitor the temperatures and control status from multiple clients.
How can I make sure that no matter which client accesses the server, they all see the same state of the server?
Server code below:
var app = require('express')();
var http = require('http').createServer(app);
var socketServer = require('socket.io').listen(http);
var fs = require('fs');
var csv_stream = fs.createWriteStream("tempLog.csv");
var time_handler = require('moment');
SerialPort = require("serialport").SerialPort;
var serialPort;
var portName = '/dev/ttyACM0'; //change this to your Arduino port
var sendData = "";
var debug = false;
app.get('/', function(req, res){
res.sendFile(__dirname + '/public/interface.html')
});
socketServer.on('connection', function(socket){
console.log('a user connected');
socket.on('run', function(data){
serialPort.write('Z' + data + 'A');
console.log('write to ard');
console.log('Z' + data + 'A');
});
socket.on('stop', function(data){
serialPort.write('Y' + data + 'B');
console.log('write to ard');
console.log('Y' + data + 'B');
});
socket.on('configure', function(data){
serialPort.write('X' + data + 'C');
console.log('write to ard');
console.log('X' + data + 'C');
});
socket.on('temperatureValues', function(data){
serialPort.write(data);
console.log('write data to ard');
console.log(data);
});
socket.on('timeValues', function(data){
serialPort.write(data);
console.log('write data to ard');
console.log(data);
});
});
serialListener(debug);
function SocketIO_serialemit(sendData){
//console.log(sendData.length);
if(sendData.length >= 14)
{
var s_data = sendData.split(",");
socketServer.emit('temp1',{'temp': s_data[0]});
socketServer.emit('temp2',{'temp': s_data[1]});
socketServer.emit('temp3',{'temp': s_data[2]});
csv_stream.write(time_handler().format('HH:mm:ss') + ',');
csv_stream.write(s_data[0] + ',' + s_data[1] + ',' + s_data[2]);
csv_stream.write('\n');
//csv_stream.end();
}
else{
console.log("Error");
//var s_data = sendData.split(",");
//console.log(s_data[0]);
//console.log(s_data[1]);
//console.log(s_data[2]);
}
}
// Listen to serial port
function serialListener(debug)
{
var receivedData = "";
serialPort = new SerialPort(portName, {
baudrate: 9600,
// defaults for Arduino serial communication
dataBits: 8,
parity: 'none',
stopBits: 1,
flowControl: false
});
serialPort.on("open", function () {
console.log('open serial communication');
// Listens to incoming data
serialPort.on('data', function(data) {
if (data.toString() == "X")
{
console.log("Control Done");
socketServer.emit('Completed',{'key': data.toString()});
}
if (data.toString()[0] == "S")
{
console.log("Stage Done");
socketServer.emit('Stage',{'key': data.toString()[0]});
}
receivedData += data.toString();
//console.log(receivedData);
if (receivedData .indexOf('E') >= 0 && receivedData .indexOf('T') >= 0) {
sendData = receivedData .substring(receivedData .indexOf('T') + 1, receivedData .indexOf('E'));
receivedData = '';
SocketIO_serialemit(sendData);
}
});
});
}
http.listen(3000, function(){
console.log('listening on *:3000')
});
app.use(require('express').static(__dirname + '/public')); //sever static files (css, js, fonts, etc.)

using WiFly with ws websockets

I have been trying to figure out a way to connect a WiFly from an Arduino to send some accelerometer data to my node.js server. Currently the way that I have it worked out is having three servers:
Http >> This is for clients purposes
Net server >> This is basically for TCP request, this is how my server receives the information from 3. WS websockets >> this takes the data from the Net server and streams it to the client side.
Here is the code:
var http = require('http');
var fs = require('fs');
var path = require('path');
var url = require('url');
var net = require('net');
var sensorData;
var message = {
"data": ''
}
var newValue,
oldValue,
diff;
//Settings
var HTTP_PORT = 9000;
var NET_PORT = 9001;
var WS_PORT = 9002;
//Server
var mimeTypes = {
"html": "text/html",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"png": "image/png",
"js": "text/javascript",
"css": "text/css"
};
http.createServer(function (req, res) {
var fileToLoad;
if (req.url == '/') {
fileToLoad = 'index.html';
} else {
fileToLoad = url.parse(req.url).pathname.substr(1);
}
console.log('[HTTP] :: Loading :: ' + 'frontend/' + fileToLoad);
var fileBytes;
var httpStatusCode = 200;
fs.exists('frontend/' + fileToLoad, function (doesItExist) {
if (!doesItExist) {
console.log('[HTTP] :: Error loading :: ' + 'frontend/' + fileToLoad);
httpStatusCode = 404;
}
var fileBytes = fs.readFileSync('frontend/' + fileToLoad);
var mimeType = mimeTypes[path.extname(fileToLoad).split('.')[1]];
res.writeHead(httpStatusCode, {
'Content-type': mimeType
});
res.end(fileBytes);
});
// console.log("[INIT] Server running on HTTP Port");
}).listen(HTTP_PORT);
proxy.on("close", function(){
console.log("Connection has closed");
});
proxy.on("end", function(){
console.log("Connection has ended");
});
var socket;
var clients = [];
var socketObject;
var server = net.createServer(function (socket) {
socketObject = socket;
socket.name = socket.remoteAddress + ":" + socket.remotePort;
clients.push(socket);
console.log(socket);
socket.write("HTTP/1.1 101", function () {
console.log('[CONN] New connection: ' + socket.name + ', total clients: ' + clients.length);
});
socket.setEncoding('utf8');
socket.on('error', function (data) {
console.log(data);
});
socket.on('end', function () {
console.log('[END] Disconnection: ' + socket.name + ', total clients: ' + clients.length);
});
socket.on('data', function (data) {
console.log('[RECV from ' + socket.remoteAddress + "] " + data);
oldValue = newValue;
newValue = data;
diff = Math.abs(newValue) - Math.abs(oldValue);
console.log(Math.abs(newValue) + '-' + Math.abs(oldValue));
message.data = Math.abs(diff);
console.log('[SAVED] ' + message.data);
});
});
server.listen(NET_PORT, function () {
console.log("[INIT] Server running on NET server port", NET_PORT);
});
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({
port: WS_PORT
});
wss.on('connection', function (ws) {
// ws.send(JSON.stringify(message));
setInterval(function () {
updateXData(ws)
}, 500);
});
function updateXData(ws) {
var newMessage = {
"data": ""
}
newMessage.data = message.data
ws.send(JSON.stringify(newMessage));
}
So the question is: Is there a cleaner way to do this just by using ws to handle the data from the WiFly and then sending it to the client?
Thanks in advance!
Not sure whether this will suit you and might be new to you but you could make use of MQTT, there are free brokers available which are very good and its relatively easy to set up and implement with Arduino equipped with WiFly Shield.
http://mqtt.org/
Hope this helps somewhat!

Resources