Res.write is not working when continuously sending UDP packet - html

//Sending UDP message to TFTP server
//dgram modeule to create UDP socket
var express= require('express'), fs= require('fs'),path = require('path'),util = require('util'),dgram= require('dgram'),client= dgram.createSocket('udp4'),bodyParser = require('body-parser'),app = express(), ejs = require('ejs');
var plotly = require('plotly')("Patidar", "ku0sisuxfm")
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(express.static('public'));
//Reading in the html file for input page
app.get('/', function(req, res){
var html = fs.readFileSync('index2.html');
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(html);
});
//reading in html file for output page
app.get('/output', function(req, res){
var html = fs.readFileSync('index4.html');
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(html);
});
//Recieving UDP message
app.post('/output', function(req, res){
var once= req.body.submit;
if (once == "Once") {
//Define the host and port values of UDP
var HOST= req.body.ip;
var PORT= req.body.port;
//Reading in the user's command, converting to hex
var message = new Buffer(req.body.number, 'hex');
//Sends packets to TFTP
client.send(message, 0, message.length, PORT, HOST, function (err, bytes) {
if (err) throw err;
});
//Recieving message back and printing it out to webpage
client.on('message', function (message) {
fs.readFile('index3.html', 'utf-8', function(err, content) {
if (err) {
res.end('error occurred');
return;
}
var temp = message.toString(); //here you assign temp variable with needed value
var renderedHtml = ejs.render(content, {temp:temp, host: HOST, port: PORT}); //get redered HTML code
res.end(renderedHtml);
//var data = [{x:[req.body.number], y:[temp], type: 'scatter'}];
//var layout = {fileopt : "overwrite", filename : "simple-node-example"};
//plotly.plot(data, layout, function (err, msg) {
//if (err) return console.log(err);
//console.log(msg);
//});
});
});
}
if (once == "continuous") {
var timesRun = 0;
var requestLoop = setInterval(function(){
timesRun += 1;
if(timesRun === 5){
clearInterval(requestLoop);
}
//Define the host and port values of UDP
var HOST= req.body.ip;
var PORT= req.body.port;
//Reading in the user's command, converting to hex
var message = new Buffer(req.body.number, 'hex');
//Sends packets to TFTP
client.send(message, 0, message.length, PORT, HOST, function (err, bytes) {
if (err) throw err;
});
//Recieving message back and printing it out to webpage
client.on('message', function (message) {
fs.readFile('index3.html', 'utf-8', function(err, content) {
if (err) {
res.end('error occurred');
return;
}
var temp = message.toString(); //here you assign temp variable with needed value
var renderedHtml = ejs.render(content, {temp:temp, host: HOST, port: PORT}); //get redered HTML code
res.write(renderedHtml);
//var data = [{x:[req.body.number], y:[temp], type: 'scatter'}];
//var layout = {fileopt : "overwrite", filename : "simple-node-example"};
//plotly.plot(data, layout, function (err, msg) {
//if (err) return console.log(err);
//console.log(msg);
//});
});
});
}, 10000);
}
});
//Setting up listening server
app.listen(3000, "192.168.0.136");
console.log('Listening at 192.168.0.136:3000');
I have two button, one button sends the UDP packet once, while a continuous button sends the same UDP packets every 10 seconds. However, when this button is pressed, res.write is repeating the entire output again. Look at the attached pic to see output[![enter image description here][1]][1]

After putting your code into an auto-code-formatter to make it readable, I can see that you are doing this:
client.on('message', function (message) { ...
inside of your app.post() handler. That means that every time your post handler is called, you add yet another client.on('message', ...) event handler. So, after it's called the 2nd time, you have two event handlers, after it's called the 3rd time, you have three and so on.
So, as soon as you have these duplicate, each will get called and you will get duplicate actions applied.
Your choices are to either:
Use .once() for the event handler so it is automatically removed after it fires.
Remove it manually after it fires or when you are done with it.
Add it once outside your app.post() handler so you never add duplicates.
Restructure the way your code works so it doesn't have this type of issue. For example, you have two different handlers for the same incoming message. This is a sign of very stateful code which is more complex to write properly. A better design that isn't stateful in that way would be simpler.

Related

nodejs server app.post issue XML Parsing Error: syntax error Location: http://localhost:3000/get_messages Line Number 1, Column 1:

I followed a tutorial on YouTube to create a private user to user chat.
https://www.youtube.com/watch?v=Ozrm_xftcjQ
Everything on the chat works accept that i keep getting this Error:
XML Parsing Error: syntax error Location: http://localhost:3000/get_messages Line Number 1, Column 1:
using firefox developer edition and chrome. if i click the stack trace link i get the following xml error:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /get_messages</pre>
</body>
</html>
but i have no GET calls at all..
The code looks as follows:
server.js file
var port = process.env.PORT || 3000;
//creating express instance
var express = require("express");
var app = express();
//creating http instance
var http = require("http").createServer(app);
//app.use(express.static(__dirname));
//creating socket instance
var io = require("socket.io")(http);
//create body parser instance
var bodyParser = require("body-parser");
app.use(bodyParser.json());
//enable url encode for POST requests
app.use(bodyParser.urlencoded({ extended : true }));
//create instance of mysql
var mysql = require('mysql');
//create mysql connection
// connectionLimit: 100,debug: true
var connection = mysql.createConnection({
host: 'localhost',
user: 'xxx',
password: 'xxx',
database: 'chatio'
});
connection.connect(function(error){
if(error){
console.log(error);
return;
}
console.log('database connected');
})
//enable header request for post requests
app.use(function(request, result, next){
result.setHeader("Access-Control-Allow-Origin", "*");
next();
})
//create api to return all messages
app.post("/get_messages", function(request, result){
console.log(request);
console.log(result);
connection.query("SELECT * FROM chat_messages WHERE (`from_id` = '"+request.body.sender+"' AND `to_id` = '"+request.body.receiver+"') OR (`from_id` = '"+request.body.receiver+"' AND `to_id` = '"+request.body.sender+"')", function(error, messages){
if(error){
console.log(error);
return;
}
console.log(messages);
//response will be in JSON
result.end(JSON.stringify(messages));
});
})
io.on("connection", function(socket){
socket.on("send_message", function(data){
//send event to receiver
var socketId = users[data.receiver];
io.to(socketId).emit("new_message", data);
//save in database
connection.query("INSERT INTO chat_messages (`from_id`,`to_id`,`message`) VALUES ('"+data.sender+"', '"+data.receiver+"', '"+data.message+"')", function(error, result){
if(error){
console.log(error);
return;
}
console.log('message saved');
});
})
})
http.listen(port, function(){
console.log("server started");
})
inde.php file code as follows:
//creating io connection
var io = io("http://localhost:3000");
var receiver = "johnny";
var sender = "steven";
function onUserSelected(){
$.ajax({
url: "http://localhost:3000/get_messages",
method:"POST",
cache: false,
data: {
"sender" : sender,
"receiver" : receiver
},
dataType: "json",
success: function(response){
var messages = response; //JSON.parse();
var html = "";
for(var i = 0; i < messages.length; i++){
html += "<li>" +messages[i].from_id + " says: " + messages[i].message + "</li>";
document.getElementById('messages').innerHTML += html;
}
}
});
return;
}
}
i figured it out..
the problem comes from this line:
result.end(JSON.stringify(messages));
I dont exactly understand why, but i changed it to
result.send(JSON.stringify(messages));
and now the bug is gone

When database is changed value is not updating in socket.io

I have write code of socket.io and nodejs to fetch value from database and send the value to the client without refresh with setInterval. It is working fine but I don't want to use setInterval function. Because sometimes my database change in hours, sometimes in minuts and sometimes in miliseconds. So I don't want to use setInterval function. I only want that when database value change it automatically update. thats it. I am kinda stuck in it.
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var mysql = require('mysql');
users = [];
connections = [];
disconnection = [];
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'test'
});
connection.connect(function(error){
if(!!error) {
console.log('Error in connection');
} else {
console.log('Database Connected');
}
});
server.listen(process.env.PORT || 3000);
console.log('Server Running...');
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
io.sockets.on('connection', function(socket) {
connections.push(socket);
console.log('Connected: %s socket connected',
connections.length);
setInterval(function() {
connection.query('select value from piechart',
function(error, rows, fields) {
if(rows.length>0) {
io.sockets.emit('new message', {msg: rows});
//io.sockets.emit('new message', {msg:
'Change.'});
//console.log('Value is fetched from database');
//console.log(rows);
} else {
alert('what will happend');
}
//connection.release();
});
}, 3000);
});
You should take the interval out of the socket scope and make it global.
Then make an interval loop that fetches the value and emits it globally if the value changed from last time it was fetched, to all connected socket clients.
You state that you would like to avoid an interval, but at the end you are going to be needing one.
You can check out mysql-events
A Node JS NPM package that watches a MySQL database and runs callbacks
on matched events.
Another way around it, would be to find all the events that update the value and make them inform your NodeJS process.
But this might be hard if it has components that are out of your control (example : unable of adding code to other process that updates DB)

socket.io Updating all the open pages

I am trying to create a chat website, something like a discord clone. I am using socket.io to connect my front end and back-end but I cant figure out how to make it that when someone enters a message that message to be displayed on all currently open browser pages
Server.js (My server file I use):
const express = require("express");
const app = express();
const http = require("http").Server(app);
const port = 4000;
const io = require("socket.io")(http);
app.get("/", (req, res) => {
res.sendFile("ChatRoom.html", {"root": __dirname});
});
io.on("connection", (socket) => {
console.log("A user has connected");
socket.on("messageSend", (data) =>{
console.log(data);
io.emit("chatUpdate", data);
});
});
http.listen(port, () => {
console.log("Server.js listening on port " + port );
});
And my Javascript code in the HTML file:
var socket = io();
document.addEventListener('keydown', InputText);
function InputText(e)
{
//Checks if the pressed button is Enter and if the input box is empty
if( e.keyCode == 13 && document.getElementById("chat_input").value != "")
{
//Gets the div which the message will be ridden to
var parent = document.getElementById("chat");
//Current date to be used when displaying the exact time of sending the
messgae
let d = new Date()//.getTimezoneOffset();
//Getting the properties of the input
var value = document.getElementById("chat_input");
//Telling the server that a message has been sent - function
emitter(parent, value.value, d);
//Setting the text box back to blank
value.value = "";
}
}
//Function
function emitter(holder, text, date){
socket.emit("messageSend", text);
socket.once("chatUpdate", (message) => {
var z = document.createElement("p");
z.innerText = date.getHours() +":"+ date.getMinutes() + " | " +
message;
z.style = 'border-top: 1px solid Black;border-bottom: 1px solid
Black;font-size:20px; margin: 0;padding: 10px;';
holder.appendChild(z);
});
}
Once you have emitted the message you need to be listening for it in the client, if the action you are trying to achieve is sending the message to another user that has the socket currently open on their window. Because you are sending it to a user not the server, so you would need to be connecting to the socket so it's very possible your socket might need to be defined more like this.
var socket = io.connect('Your:/url/of/windowlocation/whileonsocket/here')
Hope this helps!

How to generate a pdf whenever save the data?

I need to generate a PDF whenever submitting the data from a html form. But PDF should not be a image of html page. I have used node.js for my server implementations. All the data that I have inserted from fields in the form should be included in the PDF. Also, I have used mongodb as my database.
var express=require('express');
var app=express();
var mongoose=require('mongoose');
var bodyparser=require('body-parser');
var outline=require('./schemas/outline');
var outcomes=require('./schemas/outcomes');
//making db connection
mongoose.connect('mongodb://127.0.0.1:27017/modulelist');
//checking db connection
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log("connected to db");
});
//setting client location
app.use(express.static(__dirname+"/client"));
//setting body parser
app.use(bodyparser.json());
//Insert modulelist data to db
app.post('/SaveModuleList',function(req,res){
var mod=new outline(req.body);
mod.save(function(err,docs){
if(!err){
res.json(docs);
}else{
console.log(err);
}
})
});
app.post('/SaveOutcomesList',function(req,res){
var out=new outcomes(req.body);
out.save(function(err,docs){
if(!err){
res.json(docs);
}else{
console.log(err);
}
})
});
app.listen(3000,function(){
console.log("server runing in port 3000");
});

cannot response.write on connection node.js

I wrote this code in node.js :
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('start\n');
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'hostname',
user : 'user',
password : 'pass',
database : 'dbname',
});
connection.connect();
connection.query('SELECT code FROM user_type', function(err, rows, fields) {
if (err) throw err;
//This for is to run on all the results
for(var i=0;i<2;i++){
res.write('name:',rows[i].code);
}
});
connection.end();
res.end('End');
}).listen(8080);
console.log('Server running');
my questions are:
1. why did the res.write in the for loop print nothing in my html page?
2. what to write instead of 2 in the for?
The issue is the timing of execution.
Since connection.query() is asynchronous, it delays the execution of the callback function to when the query finishes, but allows the surrounding block of code to continue in the meantime. This results in res.end('End') being executed before res.write('name:',rows[i].code).
To also delay res.end(), move it inside the callback:
connection.query(..., function(err, rows, fields) {
if (err) throw err;
for (...) {
res.write('name:',rows[i].code);
}
res.end('End');
});
rows should be an Array when there isn't an err, so you can use its length property:
for (var i = 0; i < rows.length; i++) {
It's also a common practice to store the value of length in a local variable:
for (var i = 0, len = rows.length; i < len; i++) {