-
Notifications
You must be signed in to change notification settings - Fork 1
/
longpoll.js
94 lines (88 loc) · 2.15 KB
/
longpoll.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
/*jshint esnext:true*/
//Longpolling...
WebSocket = require("ws");
connections = {};
var CLIENT_TIMEOUT = 60*1000,
CHECKRATE = 30*1000,
POLL_TIMEOUT = 30*1000;
setInterval(function(){
console.log("Checking for dead longpolls");
var keys = Object.keys(connections),
now = Date.now();
for(var i=0;i<keys.length;i++){
var proxy = connections[keys[i]];
if (proxy.lastSeen < now-CLIENT_TIMEOUT){
proxy.ws.close();
}
}
},CHECKRATE);
function connection(proxyTo,forIp){
this.proxyTo = proxyTo;
console.info("Long poll proxying to",proxyTo,"for",forIp);
this.id = undefined;
this.queue = [];
this.notify = undefined;
}
connection.prototype.getId = function(){
return new Promise(good => {
this.ws = new WebSocket("ws://"+this.proxyTo);
this.ws.on("message",d=>{
if(this.id === undefined){
var data = JSON.parse(d);
if(data.type == "self"){
this.id = data.client.id;
good(this.id);
}
}
this.queue.push(d);
if(this.notify){
this.notify();
}
});
});
};
connection.prototype.send = function(send,slave){
this.lastSeen = Date.now();
if (send) {
this.ws.send(send);
}
if (slave) {
return;
} else {
return new Promise((good,bad) => {
this.notify = good;
if(this.queue.length>0) good();
setTimeout(bad,POLL_TIMEOUT);
}).then(_=>this.queue[0])
.catch(_=>"{}")
.then(n=>{this.notify=undefined;return n;});
}
};
function longPoll(req,res){
var proxy;
if (req.query.key){
proxy = connections[req.query.key];
if (proxy === undefined){
res.json({_err:"bad key"});
} else {
var reply = proxy.send(req.query.msg,req.query.slave)
if(reply !== undefined){
reply.then(reply => res.send(reply))
.then(_=>proxy.queue.shift());
} else {
res.status(200).end();
}
}
} else {
var host = req.get("Host");
if(req.query.query){
host += "/"+req.query.query;
}
proxy = new connection(host,req.ips);
proxy.getId().then(id=>{
res.json({_key:id});
connections[id] = proxy;
});
}
}
module.exports = longPoll;