Socket.io emit doesnt work - node.js

Basically,
I first initiate socket.io like this:
var io = require('socket.io')(1337);
Then, after using http to get a POST request and check some info, I try this:
var updateArray = {timer:"start"};
jsonUpdate = JSON.stringify(updateArray);
io.emit('update', jsonUpdate);
But it doesn't send the sockets, and I really can't understand the socket.io documentation sadly, so I'd be happy if someone can help me out.
Server code:
var http = require('http');
var fs = require('fs');
var io = require('socket.io')(1337);
var initialBomb = 0;
function now() {
return Math.floor(new Date() / 1000);
}
http.createServer(function (req, res) {
var body = "";
req.on('data', function (chunk) {
if (req.method == 'POST') {
body += chunk;
}
});
req.on('end', function () {
parsedBody = JSON.parse(body);
if (parsedBody.round["bomb"] == "planted") {
var rightNow = now();
var initialCheck = initialBomb + 41;
if (rightNow > initialCheck) {
initialBomb = now();
var updateArray = {timer:"start"};
jsonUpdate = JSON.stringify(updateArray);
io.emit('update', jsonUpdate);
console.log(jsonUpdate);
}
}
});
}).listen(3000);
Client Code:
<script>
var socket = io('87.98.219.48:1337');
socket.on('update', function(payload) {
var data = JSON.parse(payload);
console.log(payload);
if (data['timer'] == 'start') {
initTick = timerNow();
setTimeout(tick, delay);
}
});
</script>

Related

get client username sent to server side in javascript

How can I pass form input from client to server in javascript? Below is the client side. I want to take a username or anything entered in textbox, and send it to server.js where it will be processed for validation. the thing is that I need the data from client.js to be stored in a variable in server.js to be able o retreive it.
var textbox;
var dataDiv;
window.onload = init;
function init(){
textbox = document.createElement("input");
textbox.id="textbox";
dataDiv = document.createElement("div");
var header = document.createElement("h1");
header.appendChild(document.createTextNode("Select User"));
var button = document.createElement("BUTTON");
button.id = "myBtn";
var textBtn = document.createTextNode("Click me");
button.appendChild(textBtn);
button.addEventListener("click", () => {
sendData();
});
var docBody = document.getElementsByTagName("body")[0];//Only one body
docBody.appendChild(header);
docBody.appendChild(dataDiv);
docBody.appendChild(textbox);
docBody.appendChild(button);
}
function sendData(){
var usrName = document.getElementById("textbox").value; //I want to send it to server.js
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var dataObj = JSON.stringify(this.responseText);
dataDiv.innerHTML = dataObj;
}
};
xhttp.open("GET", "/register", true);
xhttp.send();
}
This is the server side
var express = require('express');
var app = express();
app.get('/register', handleGetRequest); //how do I pass usrName here?
app.use(express.static('public'));
app.listen(5000);
function handleGetRequest(request, response){
var pathArray = request.url.split("/");
var pathEnd = pathArray[pathArray.length - 1];
if(pathEnd === 'register'){
response.send("{working}");
}
else
response.send("{error: 'Path not recognized'}");
}
If you use GET, you have to put the parameters in the URL.
xhttp.open("GET", "/register?usrName=" + encodeURIComponent(usrName), true);
See How to get a URL parameter in Express? for how you read the query parameter in Express.
Sending data:
function sendData(){
var usrName = document.getElementById("textbox").value; //I want to send it to server.js
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var dataObj = JSON.stringify(this.responseText);
dataDiv.innerHTML = dataObj;
}
};
xhttp.open("GET", "http://localhost:5000/register?usrName=" + encodeURIComponent(usrName), true);
xhttp.send();
}
Reading data:
function handleGetRequest(request, response){
var urlParts = request.url.split("?");
if(urlParts[0] === '/register'){
var usrName = urlParts[1].replace('usrName=', '');
response.send("{" + usrName + "}");
}
else
response.send("{error: 'Path not recognized'}");
}

multiple get requests in node js

I'm working on a facebook chatbot. I have to make several GET requests according to users response. Right now I'm making all requests at once, since I don't know how to get the response out of the request function. Is there an easier way to it?
'use strict';
var https = require('https');
var options = {
host: 'url.com',
path: '/path_to_api'
};
var req = https.get(options, function(res) {
var bodyChunks = [];
res.on('data', function(chunk) {
bodyChunks.push(chunk);
}).on('end', function() {
var body = Buffer.concat(bodyChunks);
body = ''+body;
var json_body = JSON.parse(body);
var options2 = {
host: 'url2.com',
path: '/path_to_api'
};
var req = https.get(options2, function(res) {
var bodyChunks = [];
res.on('data', function(chunk) {
bodyChunks.push(chunk);
}).on('end', function() {
var body = Buffer.concat(bodyChunks);
body = ''+body;
var json_body2 = JSON.parse(body);
})
});
Thanks
You can try create a bunch of requests with request-promise:
var rp = require('request-promise');
var requests = [
rp(options), rp(options2), rp(options3) ...
];
Promise.all(requests).then(([restul1, result2, ...allOtherResuts]) => {
//process ok
}).catch( err => {
//handle error
})

Node.js - File upload with progress

I'm trying to upload a file through curl --upload-file
For some reason, curl freezes and upload.backup get created empty. Any ideas how this code should be changed to make it work? I must be misunderstanding the APIs
var http = require('http');
var fs = require('fs');
var server = http.createServer(function(request, response) {
var fileBackup = fs.createWriteStream("upload.backup");
var fileBytes = request.headers['content-length'];
var uploadedBytes = 0;
request.on('readable', function() {
var chunk = null;
while (null !== (chunk = request.read())) {
uploadedBytes += chunk.length;
var progress = uploadedBytes / fileBytes * 100;
response.write("progress: " + parseInt(progress, 10) + "%\n");
}
});
request.pipe(fileBackup);
}).listen(8080);
One issue is that you're not ending your response. Secondly, you're reading the data from the request stream before it can be written to the file.
Try something like this instead:
var http = require('http');
var fs = require('fs');
var server = http.createServer(function(request, response) {
var fileBackup = fs.createWriteStream('upload.backup');
var fileBytes = parseInt(request.headers['content-length'], 10);
var uploadedBytes = 0;
request.pipe(fileBackup);
if (!isNaN(fileBytes)) {
request.on('data', function(chunk) {
uploadedBytes += chunk.length;
response.write('progress: ' + (uploadedBytes / fileBytes * 100) + '%\n');
});
}
request.on('end', function() {
response.end();
});
}).listen(8080);

Node.js http.get with Node.js step module

I am new to Node.js world, kind of stuck in situation.
below code is for reference:
var http = require('http');
var step = require('step');
var request = require('request');
exports.readimage2 = function(req, res){
//res.send(200,'OK');
//var image_url = 'http://www.letsgodigital.org/images/artikelen/39/k20d-image.jpg'; //--- 10mb
//var image_url = 'http://upload.wikimedia.org/wikipedia/commons/2/2d/Snake_River_(5mb).jpg';
//var image_url = 'http://www.sandia.gov/images2005/f4_image1.jpg'; //--- 2mb
var image_url = 'http://www.fas.org/nuke/guide/pakistan/pakistan.gif'; // --- some KB
http.get(image_url,
function(responseData) {
var data = new Buffer(parseInt(responseData.headers['content-length'],10));
var pos = 0;
responseData.on('data', function(chunk) {
chunk.copy(data, pos);
pos += chunk.length;
});
responseData.on('end', function () {
res.send(200, data);
});
});
};
Above code fails working for large files if i use it with step module.
Anyone suggest how to do it properly with step.
Here how i did it using step..... although the request module did same for image buffer download thanks to a post on stackoverflow just need to set encoding to null in request to work for buffer response.
var canvas = new Canvas(3000, 3000),
ctx = canvas.getContext('2d'),
Image = Canvas.Image;
var image_url = "http://www.a2hosting.com/images/uploads/landing_images/node.js-hosting.png";
//var image_url = 'http://upload.wikimedia.org/wikipedia/commons/1/16/AsterNovi-belgii-flower-1mb.jpg';
step(
function() {
request.get({
url: image_url,
encoding: null
}, this);
},
function(err, response, body) {
var img = new Image;
img.src = body;
ctx.drawImage(img, 0, 0, img.width, img.height);
//res.send(200, data);
res.send(200, '<img src="' + canvas.toDataURL() + '" />');
}
);
Below is the code working for simple http module of node.
var http = require('http');
var step = require('step');
var request = require('request');
exports.imagedownload = function(req, res){
step(
function(){
console.log('*********** image download start ***********');
fndownload(this);
},
function(err, result){
if(err) {
}
console.log('*********** image download end ***********');
res.send(200, result);
}
);
};
function fndownload(callback) {
var image_url = 'http://upload.wikimedia.org/wikipedia/commons/2/2d/Snake_River_(5mb).jpg'; // --- some KB
http.get(image_url,
function(responseData) {
var data = new Buffer(parseInt(responseData.headers['content-length'],10));
var pos = 0;
responseData.on('data', function(chunk) {
chunk.copy(data, pos);
pos += chunk.length;
});
responseData.on('end', function () {
//res.send(200, data);
callback(null, data);
});
});
};

Dealing with asynchronous functions. Custom callback?

I have the code below and am trying to access the all_records array once the _.each function has completed. However as it is asynchronous I was wondering if was possible to force a callback onto the underscores each?
var request = require('request'),
cheerio = require('cheerio'),
_ = require('underscore');
var all_records = [];
_.each([0,100], function(start) {
var base_url = "http://www.example.com/search?limit=100&q=foobar&start=";
var url = base_url + start;
request(url, function(err, res, body) {
var $ = cheerio.load(body),
links = $('#results .row');
$(links).each(function(i, link) {
var $link = $(link);
var record = {
title: $link.children('.title').text().trim()
};
all_records.push(record);
});
});
});
// Need to run this once _.each has completed final iteration.
console.log(all_records);
Here is a simple solution using a simple synchronization method:
var count = 101;//there are 101 numbers between 0 and 100 including 0 and 100
_.each([0,100], function(start) {
var base_url = "http://www.example.com/search?limit=100&q=foobar&start=";
var url = base_url + start;
request(url, function(err, res, body) {
var $ = cheerio.load(body),
links = $('#results .row');
$(links).each(function(i, link) {
var $link = $(link);
var record = {
title: $link.children('.title').text().trim()
};
all_records.push(record);
count--;
if(count===0){//101 iterations done
console.log(all_records);
}
});
});
});
A more elegant solution can be accomplied by using async's .parallel method.
var requests = []; //an array for all the requests we will be making
for(var i=0;i<=100;i++){
requests.push((function(done){ //create all the requests
//here you put the code for a single request.
//After the push to all_records you make a single done() call
//to let async know the function completed
}).bind(null,i));//the bind is that so each function gets its own value of i
}
async.parallel(requests,function(){
console.log(all_records);
});
async.each ended up being the easiest to implement.
async.each([0,100], function(start) {
var base_url = "http://www.example.com/search?limit=100&q=foobar&start=";
var url = base_url + start;
request(url, function(err, res, body) {
var $ = cheerio.load(body),
links = $('#results .row');
$(links).each(function(i, link) {
var $link = $(link);
var record = {
title: $link.children('.title').text().trim()
};
all_records.push(record);
});
});
}, function(err){
console.log(all_records);
});

Resources