49 lines
1.4 KiB
JavaScript
49 lines
1.4 KiB
JavaScript
const redis = require('redis');
|
|
|
|
module.exports = (config, onConnect, onError) => {
|
|
const client = config['modules']['hit_counter'] ? redis.createClient(config['redis']) : { connected: false, on: () => { /* ignore */ } };
|
|
|
|
client.on('connect', onConnect);
|
|
client.on('error', onError);
|
|
|
|
const visitors = {};
|
|
|
|
const count = (req, path, cb) => {
|
|
if (!client.connected) {
|
|
cb();
|
|
} else {
|
|
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
|
const key = path + ':' + ip;
|
|
const now = Date.now();
|
|
const isNewVisitor = (now - (visitors[key] || 0)) > config['hit_counter']['unique_visitor_timeout'];
|
|
visitors[key] = now;
|
|
client
|
|
.multi()
|
|
.hincrby(path, 'h', 1)
|
|
.hincrby(path, 'v', isNewVisitor ? 1 : 0)
|
|
.exec(cb);
|
|
}
|
|
};
|
|
|
|
const read = (path, cb) => {
|
|
if (!client.connected) {
|
|
cb({
|
|
hits: 0,
|
|
visitors: 0,
|
|
});
|
|
} else {
|
|
client.hgetall(path, (_, value) => {
|
|
cb({
|
|
hits: value ? value.h || 0 : 0,
|
|
visitors: value ? value.v || 0 : 0,
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
return {
|
|
count: count,
|
|
read: read,
|
|
};
|
|
};
|