Matthew Starkey
Matthew Starkey

Reputation: 757

Node server Issue

I'm a complete node newbie, and I'm running into a problem:

var http    = require("http");
var url     = require('url');
var fs      = require('fs');
var io      = require('socket.io');

var server = http.createServer(function(request, response){ 
console.log('Connection');
var path = url.parse(request.url).pathname;

switch(path){
    case '/':
        response.writeHead(200, {'Content-Type': 'text/html'}); 
        response.write('Hello World');
        break;
    case '/socket.html':
        fs.readFile(__dirname + path, function(error, data){
            if (error){
                response.writeHead(404);
                response.write("This doesn't exist - 404");
                console.log(error);
            } else {
                console.log('hi!'); // **************<---- I'm getting here
                response.writeHead(404, {'Content-Type': 'text/html'});
                response.write(data, 'utf8');
            }
        });
        break;
    default:
        response.writeHead(404);
        response.write("This page does not exist - 404");
        console.log(path);
        break;
}
response.end(); 
}); 

server.listen(8001);

io.listen(server);

I'm getting to the console.log() inside the 'else', but response.write does not output anything at all, If I console.log(data) I get

Upvotes: 0

Views: 247

Answers (2)

Passerby
Passerby

Reputation: 10080

Extending from my comment:

fs.readFile() is an asynchrnous call, which means it will simply tell Node to try to open the file, and then move on without waiting for it. So by this code:

fs.readFile(__dirname + path, function(error, data){
    if (error){
        response.writeHead(404);
        response.write("This doesn't exist - 404");
        console.log(error);
    } else {
        console.log('hi!'); // **************<---- I'm getting here
        response.writeHead(404, {'Content-Type': 'text/html'});
        response.write(data, 'utf8');
    }
});
response.end();

What this code does is:

  1. You: "Hey Node, open this file for me; when you're done, tell me";
  2. You: "End the response, I don't need that anymore.";
  3. (Unknown time later)
    Node: "Hi, the file is ready.".
    You: "Cool, now write the file to response stream."
    Node: "...WTF man, you've closed the stream!"

(OK I added the last line)

So to do what you intended, you have two options:

  1. Make the file open operation synchronously using fs.readFileSync(), so you can do the "linear" programming you're familiar with:

    try {
        var data=fs.readFileSync(__dirname+path,{"encoding":"utf8"});
        response.writeHead(200,{"Content-Type":"text/html"});
        response.write(data,"utf8");
    }catch(e){
        response.writeHead(400,{"Content-Type":"text/plain"});
        response.write("This doesn't exist -  404");
    }
    response.end();
    
  2. End the response in the callback function of fs.readFile(), not in server listener:

    switch(path){
        case '/':
            response.writeHead(200, {'Content-Type': 'text/html'}); 
            response.write('Hello World');
            response.end();/* here */
            break;
        case '/socket.html':
            fs.readFile(__dirname + path, function(error, data){
                if (error){
                    response.writeHead(404);
                    response.write("This doesn't exist - 404");
                    response.end(); /* here */
                    console.log(error);
                } else {
                    console.log('hi!');
                    response.writeHead(200, {'Content-Type': 'text/html'});
                    response.write(data, 'utf8');
                    response.end(); /* here */
                }
            });
            break;
        default:
            response.writeHead(404);
            response.write("This page does not exist - 404");
            response.end(); /* here */
            console.log(path);
            break;
    }
    //response.end(); <-- get rid of this line
    

Also please be noticed that I change 404 to 200 in the writeHead() call when file open is succeeded, I guess that's what you actually mean.

Upvotes: 1

Krasimir
Krasimir

Reputation: 13539

You should have .end called after write.

response.writeHead(404, {'Content-Type': 'text/html'});
response.write(data, 'utf8');
response.end();

http://nodejs.org/api/http.html#http_response_end_data_encoding

Upvotes: 1

Related Questions