2016-07-07 3 views
0

요청에 대한 특정 매개 변수를 기록하고 온라인으로 확인할 수있는 페이지에 인쇄 할 수있는 모듈을 만들려고 시도하면 페이지에 socket.io을 사용하여 최신 로그.NodeJS의 다음 이벤트 처리기에 요청 보내기

그리고이 모듈을 플러그인으로 사용하여이 모듈을 호출하고 초기화하면 추가 입구 점 /_logger이 응용 프로그램에 추가됩니다. 일단 페이지를 방문하면 최신 로그가됩니다. 실시간으로 업데이트됩니다. 그래서 모듈은 요청을 가로 챌 수 있습니다

function setup(httpServer) { 
    //page 
    httpServer.on("request", function (request, response) { 
     var pathname = url.parse(request.url).pathname; 
     if (pathname === '/_logger') { 
      fs.readFile(__dirname + '/logger.html', (err, data) => { 
       response.writeHead(200, { 'Content-Type': 'text/html' }); 
       response.write(data); 
       response.end(); 
      }); 
     }else{ 
      // how to give up the control for this requset 
     } 
    }); 


    var io = require('socket.io')(httpServer); 
    io.on('connection', function (socket) { 
     //TO BE DONE 
     socket.on('event', function (data) { }); 
     socket.on('disconnect', function() { }); 
    }); 
} 
module.exports = { 
    setup: setup 
} 

사용법 :

var logger= require("./logger/index"); 
var server = require('http').createServer(); 
logger.setup(server); 
server.on("request", function(req,res){ 
    //Normal logic for different application 
}); 
server.listen(3333); 

지금 문제가 요청 된 URL이 없습니다 /_logger되면, 나는이 요청의 제어를 해제해야한다는 것입니다.

 if (pathname === '/_logger') { 
      //take control 
     }else{ 
      // Nothing should be done here, it should go to the next request chain. 
     } 

문서를 읽은 후, 나는 올바른 방법을 찾을 수 없습니다.

아이디어가 있으십니까?

답변

1

낮은 수준의 NodeJS HTTP API를 사용한다고 가정합니다. 함수 구성을 사용하여 여러 핸들러를 하나의 핸들러로 구성 할 수 있습니다. 각 처리기는 req.url이 일치하지 않으면 다음 처리기로 실행을 생성해야합니다.

var http = require('http'); 

var handler1 = function(req, res) { 
    res.writeHead(200, { 'Content-Type': 'text/html' }); 
    res.write('/'); 
    res.end(); 
} 

var handler2 = function(req, res) { 
    res.writeHead(200, { 'Content-Type': 'text/html' }); 
    res.write('/Hello'); 
    res.end(); 
} 

var middleware = compose([wrapHandler('/', handler1), 
         wrapHandler('/hello', handler2)]); 

http.createServer(middleware).listen(3000); 

function wrapHandler(path, cb) { 
    return function (req, res, next) { 
     if (req.url === path) { 
      cb(req, res); 
     } else { 
      next(); 
     } 
    }; 
} 

function notFoundHandler(req, res) { 
    res.writeHead(404, { 'Content-Type': 'text/html' }); 
    res.write('No Path found'); 
    res.end();  
}; 

// adapted from koa-compose 
function compose(middleware) { 
    return function (req, res){ 
     let next = function() { 
      notFoundHandler.call(this, req, res); 
     }; 

     let i = middleware.length; 
     while (i--) { 
      let thisMiddleware = middleware[i]; 
      let nextMiddleware = next; 
      next = function() { 
       thisMiddleware.call(this, req, res, nextMiddleware); 
      } 
     } 
     return next(); 
    } 
} 

귀하의 경우 귀하가 작성할 수 있습니다.

var loggerHandler = wrapHandler('/_logger', logger.handler); 
httpServer.on('request', compose(loggerHandler, handler2, handler3)); 
+0

내가 두려워의'logger' 모듈은 별도의 플러그인으로 작동합니다 아닙니다. 즉,'logger' 모듈은 un-invasion이어야합니다. – hguser

+0

@hguser'logger.setup (server)'대신에 다음과 같이 logger 모듈로부터 핸들러를 export 할 수 있습니다 :'var logH = logger.handler; server.on ('request', 작성 ([logH, otherHandler]))'; – zeronone

+0

@hguser'wrapHandler' 함수를 사용하여 간단한 핸들러를 특정 경로로 바인딩 할 수 있습니다. – zeronone

1

httpServer.on("request", ...)은 하나의 요청 수신기입니다. 요청할 필요가 없다면 요청을 처리 할 의무가 없습니다. 아무것도 수행하지 않더라도 다른 요청 청취자는 여전히이 요청을 알립니다.

다른 요청 청취자 (있는 경우)가 있으면 요청한 청취자에서 아무 것도하지 않고 다른 청취자도 특정 요청을받을 수 있습니다. 이렇게하면 자신의 요청 리스너를 작동중인 http 서버에 추가 할 수 있으며 리스너는 지원하려는 새 라우트에만주의를 기울여야하며 다른 모든 라우트는 무시할 수 있으며 다른 리스너에 의해 처리됩니다 이미 자리에 있습니다.


이 두 가지를 더 간단하게 만들고 더 잘 제어 할 수 있도록 프레임 워크가 있습니다. 일반적으로 이러한 프레임 워크는 하나의 리스너를 사용하며 사용자가 요청을 처리 할 수있는 방법을 제공합니다. 또는 프레임 워크에 요청을 처리하지 않았으며 다른 라우트 처리기가 요청을 처리하도록 요청합니다. 이것은 여러 청취자를 보유하는 것보다 유연합니다. 모두 동일한 경로를 통보 받게됩니다.

예를 들어, 익스프레스 프레임 워크를 사용하여, 당신은이 작업을 수행 할 수 있습니다

var express = require('express'); 
var app = express(); 

// route handler for/request only when a user=xxx is in the query string 
app.get('/', function(req, res, next) { 
    // if user was included in query parameter 
    if (req.query.user) { 
     // do something specific when ?user=xxxx is included in the URL 
    } else { 
     // pass handling to the next request handler in the chain 
     next(); 
    } 
}); 

// route handler for/request that wasn't already handled 
app.get('/', function(req, res) { 
    // handle the/route here 
}); 

app.listen(80); 
+0

그러나'logger' 모듈을 사용할 수있는 모든 응용 프로그램이 표현, 연결 또는 다른 것을 기반으로 구축된다고 가정 할 수는 없습니다. – hguser

+0

그리고 언급 한 것처럼 하나의 리스너는 할 필요가 없다면 아무 것도 할 수 없다. 나의 예에서는 'request' 이벤트에 두 개의 리스너가 추가되었고 하나는 애플리케이션이고 다른 하나는'logger' 모듈이다. 요청은 먼저'logger'에 의해 처리되고 응용 프로그램은 일단 요청 된 URL이'_logger'이면 응용 프로그램 처리기가 호출되어'write after end' 오류가 발생합니다 – hguser

+0

@hguser - 완전히 설명하지 않았습니다 당신이 작업하고있는 제한들. 나는 단지 실제 프레임 워크가 하나의 핸들러에서 다음 핸들러로 요청을 전달하는 방법을 설명하고 있습니다. 그러한 프레임 워크에 액세스 할 수없는 경우 수행중인 모든 리스너를 추가하고 경로가 일치하면 요청을 처리하고 그렇지 않으면 아무것도 수행하지 않는 것입니다. 다른 http 서버 리스너에 "연결"하는 일반적인 방법은 없습니다. 그것이 Express와 같은 요청 프레임 워크가 제공하는 것입니다. 일반 http 개체는이를 제공하지 않습니다. – jfriend00

관련 문제