-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
118 lines (91 loc) · 2.83 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
var extend = require('extend');
var redis = require('redis');
var async = require('async');
var defaultOptions = {
prefix: 'online', // redis keys prefix
interval: 180, // seconds (user is offline after the time)
expireTime: 60 * 60 // seconds for data to expire in redis
};
function onlineTracker(){
this.options = {};
}
onlineTracker.prototype.init = function(options){
options = options || {};
this.options = extend(true, defaultOptions, options);
this.options.redisUrl = this.options.redisUrl || process.env.REDIS_URL;
if (this.options.redisUrl){
this.client = redis.createClient({ url: this.options.redisUrl });
this._init = true;
}
};
onlineTracker.prototype.setOnline = function(userId, prefix, cb){
if (!cb){
cb = prefix;
prefix = this.options.prefix;
}
if(!this._init) this.init();
if (!this.client) return cb && cb('No redis connection!');
var key = this.getTimeKey(prefix);
async.parallel([
this.client.sadd.bind(this.client, key, userId),
this.client.expire.bind(this.client, key, this.options.expireTime)
], cb);
};
onlineTracker.prototype.getOnline = function(time, prefix, cb){
if (!prefix) {
cb = time;
time = this.options.interval;
prefix = this.options.prefix;
}
if (!cb){
cb = prefix;
prefix = time;
time = this.options.interval;
}
if(!this._init) this.init();
if (!this.client) return cb && cb('No redis connection!');
var keys = this.getTimeKeys(time, prefix);
this.client.sunion(keys, cb);
};
onlineTracker.prototype.isOnline = function(userId, prefix, cb){
if (!cb){
cb = prefix;
prefix = this.options.prefix;
}
if(!this._init) this.init({});
if (!this.client) return cb && cb('No redis connection!');
this.getOnline(prefix, function(err, res){
if(err) return cb && cb(err);
res = res || [];
cb && cb(null, res.indexOf(userId) >= 0);
})
};
// redis sets key
// format - prefix:hh:mm
onlineTracker.prototype.getTimeKey = function(prefix){
prefix = prefix || this.options.prefix;
var date = new Date();
var hh = zerify(date.getHours());
var mm = zerify(date.getMinutes());
var ss = zerify(round(date.getSeconds(), this.options.round || 5));
return prefix + ':' + hh + ':' + mm + ':' + ss;
};
onlineTracker.prototype.getTimeKeys = function(time, prefix){
var timestamp = Date.now(), hh, mm, ss, keys= [];
var rnd = this.options.round || 5;
for(var i = 0; i < Math.ceil(time / rnd); i++){
var date = new Date(timestamp - i * rnd * 1000);
hh = zerify(date.getHours());
mm = zerify(date.getMinutes());
ss = zerify(round(date.getSeconds(), rnd));
keys.push(prefix + ':' + hh + ':' + mm + ':' + ss);
}
return keys;
};
function zerify(str){
return ('00' + str).slice(-2);
}
function round(num, div){
return Math.floor(num / div) * div;
}
module.exports = new onlineTracker();