This repository has been archived on 2026-05-02. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
GitBlog.md/src/hit_counter.js
T
2021-04-06 09:58:51 +02:00

67 lines
2.0 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, disable, cb) => {
if (!client.connected || disable) {
cb();
} else {
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
visitors[path] = (visitors[path] || {});
const now = Date.now();
const isNewVisitor = (now - (visitors[path][ip] || 0)) > config['hit_counter']['unique_visitor_timeout'];
visitors[path][ip] = now;
client
.multi()
.hincrby(path, 'h', 1)
.hincrby(path, 'v', isNewVisitor ? 1 : 0)
.exec(cb);
}
};
const cleanVisitors = (path) => {
visitors[path] = (visitors[path] || {});
const now = Date.now();
let count = 0;
for (let ip in visitors[path]) {
if ((now - visitors[path][ip]) > config['hit_counter']['unique_visitor_timeout']) {
delete visitors[path][ip];
} else {
count++;
}
}
return count;
};
const read = (path, cb) => {
if (!client.connected) {
cb({
path: path,
hits: 0,
total_visitors: 0,
current_visitors: cleanVisitors(path),
});
} else {
client.hgetall(path, (_, value) => {
cb({
path: path,
hits: value ? parseInt(value.h) || 0 : 0,
total_visitors: value ? parseInt(value.v) || 0 : 0,
current_visitors: cleanVisitors(path),
});
});
}
};
return {
count: count,
read: read,
};
};