Want to send response using web socket - javascript

As the function is doing 2 things at one time. Firstly it is uploading data into database than it is retrieving data and displaying in fron page .All i need is I want to send response using websocket to front end that data has been uploaded successfully in db and now its going to display the data
Backend Code:
loginrouter.get('/getImages',cors(),(req,res)=>{
var array = fs.readFileSync('log.txt').toString().split("\n");
for(i in array) {
var sql = "INSERT into images (urls) values ('"+array[i]+"')";
connection.query(sql, function (err, result) {
if (!err) {
var sql = " SELECT urls FROM `images`";
connection.query(sql, function (err, result) {
if (!err) {
const wss = new WebSocketServer.Server({ port: 8081 })
wss.on("connection", (ws,r) => {
ws.send('This is a message to client');
});
res.send(result)
}
});
}
})
}
})[Here is the result snippet al i need is that when the data is fully uploaded in database a web socket should send a message that the data is uploaded successfully and now we are going to retrieve it][1]
Front end code:
<html>
<head>
</head>
<body>
<button type="button" onclick="getImage(event)" > Show Images</button><br />
<h1 style="text-align: center; color: blue">Here are the Results:</h1>
<p id="demo"></p>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.2.1/axios.js"
integrity="sha512-SXo2rCaEJmbAPoxtaSjW+/hLaVCMAJ1CX8XnIP02x6/LIaWQp4GipKxQhBwL8Tn5U/K+lD9AaM4f4mXJdKnDQw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script>
function getImage(e) {
var exampleSocket = new WebSocket("wss://localhost:8000", "dummyProtocol");
exampleSocket.onopen = function (event) {
exampleSocket.send("WebSocket is really cool");
};
e.preventDefault();
console.log("hii");
axios
.get(
"http://localhost:8000/getImages",
{},
{
headers: { "Content-Type": "application/json" },
}
)
.then((response) => {
console.log(response.data);
for (let i = 0; i < 850; i++) {
console.log(response.data[i].urls)
document.getElementById(
"demo"
).innerHTML += `<img src="${response.data[i].urls}" style="border:1px solid black;margin-bottom:4px;margin-top:14px; margin-right: 20px" width="100px" height="100px"
alt="img">`;
}
});
}
</script>
</body>
</html>

You can't connect with ws to http server port
var exampleSocket = new WebSocket("wss://localhost:8000", "dummyProtocol");
Create an instance of ws server outside the route
loginrouter.get('/getImages'
After you uploaded your data to database, send response to the user by http that the work was done, and here you have two ways to send data by ws to user.
3.1 User gets response by http that the work was done and send a request by ws to retrieve some data.
3.2 at route getImages after sending http response, send data by ws if user already connected.
Something like this. It's not working code, only the way where you can go.
const clients = new Map();
const wss = new WebSocketServer.Server({ port: 8081 })
wss.on("connection", (ws,r) => {
ws.send('This is a message to client');
const id = uuidv4();
clients.set(id, ws);
});
loginrouter.get('/getImages',cors(),(req, res)=>{
connection.query(sql, function (err, result) {
if (!err) {
res.send(result);
clients.get(req.cookies.id).send(what_you_want_to_send)
}
});
})

Related

I'm unable to send a response to my react.js using http.get in node

I'm trying to get the temperature data from my node.js backend sent to react.js but i kept getting res.send is not a funtion
Sample code here
app.get("/gettemperature", (req, res) => {
const email = req.query.email;
let stmt = `SELECT * FROM users WHERE email=?`;
let todo = [email];
db.query(stmt, todo, (err, results, fields) => {
if (err) {
console.error(err.message);
}
if(results.length > 0 ){
let id = results[0].id;
let getID = `SELECT * FROM controlModules WHERE deviceowner=?`;
let getidData = [id];
db.query(getID, getidData, (err, resulta, fields) => {
if (err) {
console.error(err.message);
}
if(resulta.length > 0){
let lanip = resulta[0].ipaddress;
let url = "http://"+lanip+"/data";
http.get(url,(res) => {
let body = "";
res.on("data", (chunk) => {
body += chunk;
});
res.on("end", () => {
try {
let json = JSON.parse(body);
const temp_actual = json.temperature.value;
console.log(temp_actual);
res.setHeader('Content-Type', 'application/json');
res.end(
JSON.stringify({
value: temp_actual
})
);
} catch (error) {
console.error(error.message);
};
});
}).on("error", (error) => {
console.error(error.message);
});
}
});
}
});
});
i really need to return/send/respond the temperature data to my front end but i'm getting said error, is there a different way to return data?
It looks like you are mixing up an HTTP server you wrote in Node (although you haven't shown any relevant code) and an HTTP client you also wrote in Node.
res is an argument received by the callback you pass to http.get and contains data about the response received by your HTTP client.
Meanwhile, somewhere else (not shown) you have a different variable also called res which is the object your HTTP server uses to send its response to the browser running your React code.
You are calling res.send and wanting res to be the latter but it is really the former.
Since you haven't shown us the HTTP server code, it is hard to say where that res is, but there is a good chance you have shadowed it and can solve your problem by using different names (e.g. client_res and server_res).
That said. I strongly recommend avoiding using the http module directly as the API follows out of date design patterns and isn't very friendly. Consider using fetch or axios for making HTTP requests and Express.js for writing HTTP servers.

Redis stream command passing message with parsed value

I am creating the client using Redis and node js, I want to add a message to stream with the below format. I am facing an issue when trying the parse the message with the request body value.
async function userRegister (request) {
var userID = request.body.userID
var username = request.body.userName
redisClient.xadd(
'user:create',
'*',
'module',
`userRegister`,
'request_id',
'2312432434',
'message',
`{"module":"*","user_id":"1","username":"fffff"}`, // this works bcoz its string.
`{"module":"*","userID":"1","username":"here i need pass the above request body value"}`,
function (err, resp) {
if (err) {
console.log(err)
} else {
console.log(resp)
}
}
)
}

Reading a stream over HTTP with Javascript

I am trying to build a web app to stream music. I use MongoDB to store the audio, a Node API to connect to the database and a Vuejs frontend. Below is the endpoint which streams the music, based on this article: https://medium.com/#richard534/uploading-streaming-audio-using-nodejs-express-mongodb-gridfs-b031a0bcb20f
trackRoute.get('/:trackID', (req, res) => {
try {
var trackID = new ObjectID(req.params.trackID);
} catch (err) {
return res.status(400).json({ message: "Invalid trackID in URL parameter. Must be a single String of 12 bytes or a string of 24 hex characters" });
}
res.set('content-type', 'audio/mp3');
res.set('accept-ranges', 'bytes');
let bucket = new mongodb.GridFSBucket(db, {
bucketName: 'tracks'
});
let downloadStream = bucket.openDownloadStream(trackID);
downloadStream.on('data', (chunk) => {
res.write(chunk);
});
downloadStream.on('error', () => {
res.sendStatus(404);
});
downloadStream.on('end', () => {
res.end();
});
});
I tested it with Postman and it works there. I am trying to read the stream in my Vuejs application. I'm just not sure how to do it. I tried the following to test it:
const url = 'http://localhost:4343/api/track/6061c90b2658b9001e65311d';
http.get(url, function (res) {
res.on('data', function (buf) {
console.log(buf);
});
res.on('end', function () {
console.log('ended');
});
})
This does not work however. How should I go about reading it in the frontend?

create a website uptime monitor in Node.js

I want to create a uptime monitor using NodeJS and MongoDB. I want to run a cron job in NodeJS and store the data into MongoDB. If the website response status code is not equal to 200 then it will be saved in the database. I want to make a database entry like this,
url : http://www.google.com
status_code : 500
start_time :- start time
end_time :- end time
I can run the cron job but not sure how to save the downtime in the database. As, I don't want to store every response into the database. Only when response status code is other than 200 , then it will start tracking (start_time) the URL and it keeps the time when website is back to 200 as end_time.
cron.js :-
var async=require('async');
const Entry = require('../models/health.model.js');
var https = require('https');
var request = require('request');
module.exports = function getHttpsRequests () {
Entry.find({},function(err,entrys){
console.log(err);
if(!err && entrys){
async.each(entrys,function(entry,callback){
request(entry.url, function (error, response, body) {
entry.statuscheck=response.statusCode;
entry.save();
callback();
});
},function (error) {
});
}
});
}
health.model.js :-
const mongoose = require('mongoose');
const EntrySchema = mongoose.Schema({
url: String,
statuscheck: String
}, {
timestamps: true
});
module.exports = mongoose.model('Entry', EntrySchema);
I would do something like this to handle updating the database. I went ahead and put standard arrow functions in, because it was easier for me that way. I put some comments in so that should clear most questions up. It may not be the most elegant solution because I wrote it in 5 minutes, but if you follow this general logic flow, you should be much closer to your solution (its completely untested mind you.)
var async=require('async');
const Entry = require('../models/health.model.js');
var https = require('https');
var request = require('request');
module.exports = function getHttpsRequests () {
Entry.find({}, (err,entrys) => {
console.log(err);
if (!err && entrys) {
async.each(entrys, (entry,callback) => {
request(entry.url, (error, response, body) => {
//first check if the url has a document in the db.
Entry.find({ url: entry.url }, (err, entry) => {
if(!entry) {
//since the document does not exist, check the statusCode.
if(response.statusCode===200) { //if the statusCode is 200, continue the loop.
callback();
} else { //if the status code is not 200, lets save this to the db.
console.log("Saving object: " + entry)
entry.status_code = response.statusCode;
entry.start_time = new Date();
entry.save();
callback();
}
} else if (entry) {
//since the document exists, lets check the statusCode.
if(response.statusCode===200) { //if the statusCode is 200, update the stop_time.
entry.end_time = new Date();
Entry.findOneAndUpdate({ url: entry.url }, entry, (err, object) => { //this returns the entry after update, so we can put that in the console for easy debug.
if (err) {
console.log(err);
callback();
} else {
console.log("Object saved: " + object);
callback();
}
});
}
} else { //there was an error finding the document in the db, just go to the next one.
callback();
});
});
});
}
});
}

Sails + Braintree : Unable to send the transactions details to client

I'm developing an application using Sails JS and Braintree. I'm trying to send the all past transaction details that the customer has made.
Here is my getTransaction action
getTransaction: function(req, res) {
var customerId = req.param('customerId');
var gateway = setUpGateway();
var stream = gateway.transaction.search(function(search) {
search.customerId().is(customerId);
}, function(err, response) {
if (err) {
return res.serverError(err);
}
res.send(response);
});
},
But the problem is, if I directly send the response which I got from braintree server, it throws the circular dependency error. So, to overcome that error I'm fetching only those details that I need from response like this
getTransaction: function(req, res) {
var customerId = req.param('customerId');
var gateway = setUpGateway();
var stream = gateway.transaction.search(function(search) {
search.customerId().is(customerId);
}, function(err, response) {
if (err) {
return res.serverError(err);
}
var transactions = [];
response.each(function(err, transaction) {
var temp = [];
temp.push(transaction.id);
temp.push(transaction.amount);
temp.push(transaction.createdAt);
transactions.push(temp);
});
res.send(transactions);
});
},
But here the .each function is getting executed asynchronously and hence res.send returns the empty array. So what should I do to return all the transaction that the user has made?
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact our support team.
You are correct that the iterator executes asynchronously. You should use Node's stream semantics to process the request
getTransaction: function(req, res) {
var customerId = req.param('customerId');
var gateway = setUpGateway();
var transactions = [];
var stream = gateway.transaction.search(function(search) {
search.customerId().is(customerId);
});
stream.on('data', function (transaction) {
transactions.push(transaction);
});
stream.on('end', function () {
res.send(transactions);
});
},
This will wait until all transactions have been processed before sending the result.
This page provides more information about searching using our Node client library and Node's Stream API.

Categories

Resources