我正在尝试创建一个模块,可以为请求记录某些某些参数并将其打印到可以在线检查的页面,该页面将使用socket.io
加载最新的日志。
我希望这个模块可以作为一个插件工作,这意味着你只需要调用这个模块,并初始化它,然后一个额外的入口点/_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);
现在的问题是,一旦请求的网址不是/_logger
,我就应该释放对此请求的控制权。
if (pathname === '/_logger') {
//take control
}else{
// Nothing should be done here, it should go to the next request chain.
}
阅读完文件后,我找不到正确的方法。
有什么想法吗?
答案 0 :(得分: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));
答案 1 :(得分:1)
httpServer.on("request", ...)
只是一个请求侦听器。如果不需要,它没有义务处理请求。即使它什么都不做,任何其他请求监听器仍会收到此请求的通知。
如果有其他请求侦听器(您暗示有),那么您可以在您显示的请求侦听器中不执行任何操作,其他侦听器也将获取特定请求的镜头。这允许您将自己的请求侦听器添加到工作的http服务器,并且您的侦听器只需要关注它想要支持的新路由,并且可以忽略所有其他路由,并且它们将由其他侦听器处理。已经到位。
现在,有一些框架可以使这个更简单,并为您提供更多控制。通常,这些框架使用一个侦听器,它们为您提供处理请求的方法,或者明确告诉框架您没有处理请求,并希望其他路由处理程序能够处理请求。这比仅拥有多个侦听器更灵活,所有侦听器都会收到相同路由的通知。
例如,使用Express框架,您可以执行以下操作:
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);