Node.js Simple Server Request End Event Issue - node.js

I'm new to node.js. Trying to get a console to print when the request ends. I try to go to localhost:8080 and also localhost:8080/ but nothing prints in the terminal. Any idea why? Doing this because when I run this example because when I try to run the demo at http://tutorialzine.com/2012/08/nodejs-drawing-game/ the terminal says socket started but it does not render the index.html page. So I can't figure out why this code to serve static files for other is not working for me.
var static = require('node-static');
//
// Create a node-static server instance to serve the './public' folder
//
// var file = new(static.Server)('./');
require('http').createServer(function (request, response) {
request.addListener('end', function () {
console.log("ended");
});
}).listen(8080);

It seems that your are using Node.js 0.10.x and in the new version you have to resume the readable streams to make them emit events:
require('http').createServer(function (request, response) {
var body = '';
request.setEncoding('utf8');
request.on('readable', function () {
body+= this.read();
}
request.on('end', function () {
console.log('ended');
console.log('Body: ' + body);
});
request.resume();
}).listen(8080);

You should be call node-static serve inside the request handler so that you can get index.html
var static = require('node-static');
var fileServer = new static.Server('./');
require('http').createServer(function (request, response) {
fileServer.serve(request, response); //add this line
request.addListener('end', function () {
console.log("ended");
});
}).listen(8080);

Related

NodeJS server results in timeout

I have a NodeJS server script, which works like a charm on my local dev environment. But in (beta) production the webserver times out at every request. I've set this up fairly straight forward but I'm unsure how to fix it - or even where to look for a solution. Below is a simplified implementation, my logic for handling post request has been removed. What am I overlooking?
var requestListener = '';
// define the request listener, to handle incoming requests
requestListener = function (req, res) {
try {
if (req.method == 'POST') {
var queryString = '';
req.on('data', function (data) {
queryString += data;
});
req.on('end', function () {
// my logic is in here
res.end(JSON.stringify({ err: false, msg: 'all fine' }));
});
}
res.writeHead(200);
res.end();
} catch (error) {
res.writeHead(400);
res.end(error);
}
}
// boot the webserver
server = http.createServer(requestListener);
server.listen(8080);

Want to write capture and re-transmit http/https request to Browser?

I want to write a simple Node Js application which will capture and re-transmit http/https request to Browser?
I have written the below code, but it works only for http request.
var server = http.createServer(function (req,res) {
console.log("start request:", req.url);
var option = url.parse(req.url);
option.headers = req.headers;
var proxyrequest = http.request(option, function (proxyresponce) {
proxyresponce.on('data', function (chunk) {
console.log("proxy responce length" ,chunk.length);
res.write(chunk,'binary');
});
proxyresponce.on('end',function () {
console.log("proxy responce ended");
res.end();
});
res.writeHead(proxyresponce.statusCode, proxyresponce.headers);
});
});

socket.io communication between nodejs scripts

I'm trying to setup some socket.io communications, the communication between my server (app.js)(runs on a raspberry pi) and a website(public/index.html) works fine. Now I want to expand it so when my app.js receives a call from index.html it emits it further to another node.js script(bed.js) that will run on another raspberry pi. I tried to use the npm module socket.io-client, but this can only receive apparently
!edit! problem has narrowed down to the setrgb part, there it won't emit.
!edit 2! when i receive setRGB, i emit setRGBclient, but that can only be received in bed.js, not in index.html, there lays my problem, i need to share the connections or force it to another connection, no clue how i fix it though
APP.JS:
let http = require('http').createServer(handler); //require http server, and create server with function handler()
let fs = require('fs'); //require filesystem module
let io = require('socket.io')(http) //require socket.io module and pass the http object (server)
let delay = require('delay');
console.log('Define each color from RGB Strip light.');
http.listen(8080); //listen to port 8080
function handler (req, res) { //create server
fs.readFile(__dirname + '/public/index.html', function(err, data) { //read file index.html in public folder
if (err) {
res.writeHead(404, {'Content-Type': 'text/html'}); //display 404 on error
return res.end("404 Not Found");
}
res.writeHead(200, {'Content-Type': 'text/html'}); //write HTML
res.write(data); //write data from index.html
return res.end();
});
}
io.sockets.on('connection', function (socket) {// WebSocket Connection
socket.on("test", function(){
console.log("sampletext");
});
socket.on("setRGB", function(data){
socket.emit("setRGBClient", data);
console.log(data);
console.log("test");
});
});
bed.js:
let socket = require('socket.io-client')('http://localhost:8080');
let lightstate = false;
let stayOff = false;
let fadeState = false;
console.log("check");
socket.emit("test");
socket.on("setRGBClient" ,function(data) {
console.log(data);
});
I can just broadcast setRGBClient.
socket.broadcast.emit("setRGBClient", data);
I guess this is a learning exercise. Otherwise I’d caution against socket.io for such applications.
However I can only see the subscription for ‘setRGB’ not the emit-part.

See client download progress from server

Currently, I have a lot of linux based clients downloading firmware updates from my webserver.
After the client has successfully downloaded the firmware file, my server needs to execute a few scripts, which logs in to the client and performs some tasks.
Is there a way for a node server to keep track of the clients download progress, so I can execute the needed scripts once the file has been downloaded?
Ok so I will try.
If you serve your Firmware as static files through Apache/Nginx and direct url call. You don't get the progress inside your NodeJS script.
If you serve your files via stream inside a express controller you can listen to the progress. Look at this answer here https://stackoverflow.com/a/42273080/3168392
You will have to use a socket connection to make sure the node server gets update from the client of the progress of the file being downloaded.
Something like this
CLIENT_CODE
var socket = io('http://localhost');
socket.on('connect', function(){});
socket.on('data_reciving', parts.pop(),function(percentage){
if(parse_data(percentage) === 100){
client.socket.emit('downloadCompleted', {fileName:'test'});
}else{
//do nothing
}
});
SERVER_CODE:
sockets.on('connection', function (socket) {
//listen to the event from client
socket.on('downloadCompleted', function (data) {
connect_to_client();
do_some_operation();
socket.emit('ALLDONE',{some_data});
});
});
I guess this helps ,you can use this post for reference.
If you just want to run some code when a download has finished, you can use on-finished:
const onFinished = require('on-finished');
app.use((req, res, next) => {
onFinished(res, (err, res) => {
...log some data, perform some housekeeping, etc...
});
next();
});
As is, it will attach a "finished" listener to all responses, which is probably not what you want. Since this is plain Express middleware, you can attach it to specific routes instead (but how depends on how exactly the files are being served).
I found some code that seems to fit my needs.
With the code below, I can detect both the progress of a user's download from the server-side, and fire an event once the file transfer completes.
var http = require("http");
var fs = require("fs");
var filename = "./large-file";
var serv = http.createServer(function (req, res) {
var sent = 0;
var lastChunkSize = 0;
var stat = fs.statSync(filename);
res.setHeader('Content-disposition', 'attachment; filename=large-file.iso');
res.setHeader('Accept-Ranges', 'bytes');
res.setHeader('Keep-Alive', 'timeout=5, max=100');
res.writeHeader(200, {"Content-Length": stat.size});
var fReadStream = fs.createReadStream(filename, { highWaterMark: 128 * 1024 });
fReadStream.on('data', function (chunk) {
if(!res.write(chunk)){
fReadStream.pause();
lastChunkSize = chunk.length;
console.log('Sent', sent, 'of', stat.size);
}
});
fReadStream.on('end', function () {
console.log('Transfer complete.');
res.end();
});
res.on("drain", function () {
sent += lastChunkSize;
fReadStream.resume();
});
});
serv.listen(3001);

expressjs - piping to response stream doesn't work

I have this basic express app:
var express = require('express');
var app = express();
var PORT = 3000;
var through = require('through');
function write(buf) {
console.log('writing...');
this.queue('okkkk');
}
function end() {
this.queue(null);
}
var str = through(write, end);
/* routes */
app.get('/', function(req, res){
res.send("Hello!");
})
app.post('/stream', function(req, res){
var s = req.pipe(str).pipe(res);
s.on('finish', function() {
console.log('all writes are now complete.'); // printed the first time
});
});
/* listen */
app.listen(PORT, function () {
console.log('listening on port ' + PORT + '...');
});
When I post some data to /stream endpoint for the first time after starting the server I get okkk as the response which is what I expect. However, after that, any requests to /stream endpoint just timeout and not return any response.
Why is it so? What's exactly happening here?
I had this same problem and looks like res was not being finished properly. So I added a callback to my stream and ended que res myself. That fixed my problem:
stream.on('end', () => res.end());
stream.pipe(res);
It worked when I replaced req.pipe(str).pipe(res) with req.pipe(through(write, end)).pipe(res) which essentially makes sure that a new instance of through stream is created for every request.

Resources