diff --git a/notwebsocket.js b/notwebsocket.js index 8cee92f0..ca2c72bb 100644 --- a/notwebsocket.js +++ b/notwebsocket.js @@ -1,8 +1,9 @@ +var Logger = require("./logger"); + const chars = "abcdefghijklmnopqsrtuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; - var NotWebsocket = function() { this.hash = ""; for(var i = 0; i < 30; i++) { @@ -12,21 +13,23 @@ var NotWebsocket = function() { this.pktqueue = []; this.handlers = {}; this.room = ""; + this.lastpoll = Date.now(); } NotWebsocket.prototype.emit = function(msg, data) { - //hack because something fishy is going on - if(typeof msg === "object") { - data = msg["1"]; - msg = msg["0"]; - } var pkt = [msg, data]; this.pktqueue.push(pkt); } NotWebsocket.prototype.poll = function() { - var q = this.pktqueue; - this.pktqueue = []; + this.lastpoll = Date.now(); + var q = []; + for(var i = 0; i < this.pktqueue.length; i++) { + q.push(this.pktqueue[i]); + } + this.pktqueue.length = 0; + if(q.length > 0) + console.log("sending", q.length); return q; } @@ -44,7 +47,8 @@ NotWebsocket.prototype.recv = function(urlstr) { data = js[1]; } catch(e) { - console.log("Failed to parse NWS string"); + Logger.errlog.log("Failed to parse NWS string"); + Logger.errlog.log(urlstr); } if(!msg) return; @@ -56,11 +60,32 @@ NotWebsocket.prototype.recv = function(urlstr) { } NotWebsocket.prototype.join = function(rm) { - this.room = rm; + if(!(rm in rooms)) { + rooms[rm] = []; + } + + rooms[rm].push(this); +} + +NotWebsocket.prototype.leave = function(rm) { + if(rm in rooms) { + var idx = rooms[rm].indexOf(this); + if(idx >= 0) { + rooms[rm].splice(idx, 1); + } + } } NotWebsocket.prototype.disconnect = function() { - + for(var rm in rooms) { + this.leave(rm); + } + + this.recv(JSON.stringify(["disconnect", undefined])); + this.emit("disconnect"); + + clients[this.hash] = null; + delete clients[this.hash]; } function sendJSON(res, obj) { @@ -76,6 +101,8 @@ function sendJSON(res, obj) { } var clients = {}; +var rooms = {}; + function newConnection(req, res) { var nws = new NotWebsocket(); clients[nws.hash] = nws; @@ -86,7 +113,7 @@ exports.newConnection = newConnection; function msgReceived(req, res) { var h = req.params.hash; - if(h in clients) { + if(h in clients && clients[h] != null) { if(req.params.str == "poll") { sendJSON(res, clients[h].poll()); } @@ -95,24 +122,37 @@ function msgReceived(req, res) { sendJSON(res, ""); } } + else { + res.send(404); + } } exports.msgReceived = msgReceived; function inRoom(rm) { var cl = []; - for(var h in clients) { - if(clients[h].room == rm) { - cl.push(clients[h]); + + if(rm in rooms) { + for(var i = 0; i < rooms[rm].length; i++) { + cl.push(rooms[rm][i]); } } - return { - emit: function() { - for(var i = 0; i < this.cl.length; i++) { - this.cl[i].emit(arguments); - } - }, - cl: cl + cl.emit = function(msg, data) { + for(var i = 0; i < this.length; i++) { + this[i].emit(msg, data); + } }; + + return cl; } exports.inRoom = inRoom; + +function checkDeadSockets() { + for(var h in clients) { + if(Date.now() - clients[h].lastpoll >= 2000) { + clients[h].disconnect(); + } + } +} + +setInterval(checkDeadSockets, 2000); diff --git a/www/assets/js/notwebsocket.js b/www/assets/js/notwebsocket.js index 2add0ade..59d3ae1e 100644 --- a/www/assets/js/notwebsocket.js +++ b/www/assets/js/notwebsocket.js @@ -1,5 +1,19 @@ var NotWebsocket = function() { this.connected = false; + $.getJSON(WEB_URL + "/nws/connect", function(data) { + console.log(data); + this.hash = data; + this.connected = true; + this.recv(["connect", undefined]); + this.pollint = setInterval(function() { + this.poll(); + }.bind(this), 500); + }.bind(this)); + + this.handlers = {}; +} + +NotWebsocket.prototype.reconnect = function() { $.getJSON(WEB_URL + "/nws/connect", function(data) { this.hash = data; this.connected = true; @@ -7,9 +21,14 @@ var NotWebsocket = function() { this.pollint = setInterval(function() { this.poll(); }.bind(this), 100); + }.bind(this)) + .fail(function() { + if(this.reconndelay < 10000) + this.reconndelay += 100; + setTimeout(function() { + this.reconnect(); + }.bind(this), this.reconndelay); }.bind(this)); - - this.handlers = {}; } NotWebsocket.prototype.emit = function(msg, data) { @@ -17,9 +36,10 @@ NotWebsocket.prototype.emit = function(msg, data) { setTimeout(function() { this.emit(msg, data); }.bind(this), 100); + return; } var pkt = [msg, data]; - var str = escape(JSON.stringify(pkt)); + var str = escape(JSON.stringify(pkt)).replace(/\//g, "%2F"); $.getJSON(WEB_URL+"/nws/"+this.hash+"/"+str, function(){}); } @@ -33,18 +53,34 @@ NotWebsocket.prototype.poll = function() { if(!this.connected) return; $.getJSON(WEB_URL+"/nws/"+this.hash+"/poll", function(data) { + if(data.length > 0) + console.log("receiving", data.length); for(var i = 0; i < data.length; i++) { - console.log("DBG", data[i]); - this.recv(data[i]); + try { + this.recv(data[i]); + } + catch(e) { } } + }.bind(this)) + .fail(function() { + this.disconnect(); }.bind(this)); } NotWebsocket.prototype.recv = function(pkt) { var msg = pkt[0], data = pkt[1]; - if(!(msg in this.handlers)) + if(!(msg in this.handlers)) { return; + } for(var i = 0; i < this.handlers[msg].length; i++) { this.handlers[msg][i](data); } } + +NotWebsocket.prototype.disconnect = function() { + this.recv(["disconnect", undefined]); + clearInterval(this.pollint); + this.connected = false; + this.reconndelay = 100; + this.reconnect(); +}