'Computer/javascript'에 해당되는 글 23건

  1. 2013.02.02 [node.js] HTTP Server 만들기
반응형

* node.js로 HTTP 를 이용한 서버를 쉽게 만들 수 있다.

var http=require('http');

var server=http.createServer();

server.on('request',function(req,res){

        res.writeHead(200,{'Content-Type':'text/plain'});

        res.write('Hello World');

        res.end();

});

server.listen(4000);

- server.listen(port,hostname)으로 서버를 실행하며, server.close()로 서버를 종료한다. 

- server는 요청이 들어오면 'request'라는 이벤트를 발생시키며 HTTP BODY가 전송되면 'data'라는 이벤트를 발생시킨다.

- 실행후 브라우저에서 localhost:4000을 접근하면 Hello World라는 메시지를 볼 수 있다. 이 코드는 다음과 같이 줄일 수 있다.

 require('http').createServer(function(req,res){

        res.writeHead(200,{'Content-Type':'text/plain'});

        res.end('Hello World');

}).listen(4000);

- request event발생시 HTTP.SERVERREQUEST 객체가 전달 된다. 이 객체는 다음의 properties를 가진다.

 1) req.url : 요청된 url를 전달한다. url은 protocol과 host:port를 제외한 값이다.

 2) req.method : 요청된 HTTP Method를 전달한다.

 3) req.headers : 요청된 HTTP Header에 대한 객체를 전달한다. key값은 소문자이다. (예를 들어 Content-Type 은 content-type으로 보여짐

 다음은 req의 properties를 출력한 예제이다.

var http=require('http');

var server=http.createServer();

var util=require('util');

server.on('request',function(req,res){

        res.writeHead(200,{'Content-Type':'text/plain'});

        res.write(req.url+'\n');

        res.write(req.method+'\n');

        res.write(util.inspect(req.headers));

        res.end();

});

server.listen(4000);

- request event 발생시 HTTP.SERVERRESPONSE 객체도 전달 된다. 이 객체로 header와 body를 write할 수 있다.

 - writeHead대신에 res.setHeader(name,value)로 개발 설정이 가능하며 헤더 설정은 res.write() 또는 res.end() 메소드로 body 데이터를 보내기 전에만 동작하며 res.writeHead() 로 헤더를 미리 보낸 경우는 동작하지 않는다.

 - res.removeHeader('Cache-Control'); 와 같이 헤더의 값을 제거 가능하다.


* node의 장점중에 하나는 여러 소스에서 stream을 쉽게 중지하거나 시작이 가능하다는 것이다. HTTP의 경우 HTTP chunked encoding으로 Body Size를 지정하지 않고 데이터를 지속적으로 전송 가능하다. Node에서는 다음의 헤더를 HTTP 에 보낸다. "Transfer-Encoding: chunked"


* 다음과 같이 File을 Pipe로 보낼 수 있다.

var fs=require('fs');

require('http').createServer(function(req,res){

        res.writeHead(200,{'Content-Type':'video/mp4'});

        var rs=fs.createReadStream('./test.mp4');

        rs.pipe(res);

}).listen(4000);

브라우저에서 다음과 같이 동영상이 플레이 된다.

  - 또는 다른 프로세스의 Output을 Piping가능하다.

var spawn=require('child_process').spawn;

require('http').createServer(function(req,res){

        var child=spawn('tail',['-f','/var/log/system.log']);

        child.stdout.pipe(res);

        res.on('end',function(){

                child.kill();

        });

}).listen(4000);

 브라우저에서 다음과 같이 시스템 로그가 출력된다.



* 다음은 HTTP를 이용하여 파일의 출력해주는 예제이다.

 var path=require('path'),fs=require('fs');

require('http').createServer(function(req,res){

        var file=path.normalize('.'+req.url);

        console.log('Trying to serve',file);

        function reportError(err){

                console.log(err);

                res.writeHead(500);

                res.end('Internal Server Error');

        }

        path.exists(file,function(exists){

                if(exists){

                        fs.stat(file,function(err,stat){

                                var rs;

                                if (err){

                                        return reportError(err);

                                }

                                if (stat.isDirectory()){

                                        res.writeHead(403);

                                        res.end('Forbidden');

                                } else {

                                        rs=fs.createReadStream(file);

                                        rs.on('error',reportError);

                                        res.writeHead(200);

                                        rs.pipe(res);

                                }

                        });

                } else {

                        res.writeHead(404);

                        res.end('Not Found');

                }

        });

}).listen(4000);


* 다음은 주기적으로 timestamp를 전송하는 예제이다. 

 require('http').createServer(function(req,res){

        res.writeHead(200,{'Content-Type':'text/plain'});

        var left=10;

        var interval=setInterval(function() {

                for(var i=0;i<100;i++){

                        res.write(Date.now()+" ");

                }

                if(--left===0){

                        clearInterval(interval);

                        res.end();

                }

        },1000);

}).listen(4000);


반응형
Posted by alias
,