From 53c0418c62d8a2b558cba63dc4423f0b12a42808 Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Wed, 22 Jun 2016 14:24:16 -0700 Subject: [PATCH] Implemented keep alive heartbeat --- src/js/control-view.js | 5 +-- src/js/sock.js | 87 ++++++++++++++++++++++++++++++++++++++++++ src/py/bbctrl/Web.py | 24 +++++++++--- 3 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 src/js/sock.js diff --git a/src/js/control-view.js b/src/js/control-view.js index fb90fd0..289e6fe 100644 --- a/src/js/control-view.js +++ b/src/js/control-view.js @@ -1,6 +1,7 @@ 'use strict' var api = require('./api'); +var Sock = require('./sock'); function is_array(x) { @@ -63,11 +64,10 @@ module.exports = { methods: { connect: function () { - this.sock = new SockJS('//' + window.location.host + '/ws'); + this.sock = new Sock('//' + window.location.host + '/ws'); this.sock.onmessage = function (e) { var data = e.data; - console.debug('msg: ' + JSON.stringify(data)); if (typeof data == 'object') for (var key in data) @@ -80,7 +80,6 @@ module.exports = { this.sock.onclose = function (e) { this.status = 'disconnected'; - setTimeout(this.connect, 2000); }.bind(this); }, diff --git a/src/js/sock.js b/src/js/sock.js new file mode 100644 index 0000000..244a046 --- /dev/null +++ b/src/js/sock.js @@ -0,0 +1,87 @@ +'use strict' + + +var Sock = function (url, retry, timeout) { + if (!(this instanceof Sock)) return new Sock(url, retry); + + if (typeof retry == 'undefined') retry = 2000; + if (typeof timeout == 'undefined') timeout = 5000; + + this.url = url; + this.retry = retry; + this.timeout = timeout; + + this.connect(); +} + + +Sock.prototype.onmessage = function () {} +Sock.prototype.onopen = function () {} +Sock.prototype.onclose = function () {} + + +Sock.prototype.connect = function () { + console.debug('connecting to', this.url); + this.close(); + + this._sock = new SockJS(this.url); + + this._sock.onmessage = function (e) { + console.debug('msg:', e.data); + this._set_timeout(); + this.onmessage(e); + }.bind(this); + + + this._sock.onopen = function () { + console.debug('connected'); + this._set_timeout(); + this.onopen(); + }.bind(this); + + + this._sock.onclose = function () { + console.debug('disconnected'); + this._cancel_timeout(); + + this.onclose(); + if (typeof this._sock != 'undefined') + setTimeout(this.connect.bind(this), this.retry); + }.bind(this); +} + + +Sock.prototype._set_timeout = function () { + this._cancel_timeout(); + this._timeout = setTimeout(this._timedout.bind(this), this.timeout); +} + + +Sock.prototype._timedout = function () { + console.debug('connection timedout'); + this._timeout = undefined; + this._sock.close(); +} + + +Sock.prototype._cancel_timeout = function () { + clearTimeout(this._timeout); + this._timeout = undefined; +} + + +Sock.prototype.close = function () { + if (typeof this._sock != 'undefined') { + var sock = this._sock; + this._sock = undefined; + sock.close(); + } +} + + +Sock.prototype.send = function (msg) { + this._sock.send(msg); +} + + +module.exports = Sock diff --git a/src/py/bbctrl/Web.py b/src/py/bbctrl/Web.py index 3ac8ece..cbd511f 100644 --- a/src/py/bbctrl/Web.py +++ b/src/py/bbctrl/Web.py @@ -114,17 +114,31 @@ class FileHandler(APIHandler): class Connection(sockjs.tornado.SockJSConnection): + def heartbeat(self): + self.timer = self.app.ioloop.call_later(3, self.heartbeat) + self.send_json({'heartbeat': self.count}) + self.count += 1 + + + def send_json(self, data): + self.send(str.encode(json.dumps(data))) + + def on_open(self, info): - self.session.server.app.clients.append(self) - self.send(str.encode(json.dumps(self.session.server.app.state))) + self.app = self.session.server.app + self.timer = self.app.ioloop.call_later(3, self.heartbeat) + self.count = 0; + self.app.clients.append(self) + self.send_json(self.session.server.app.state) def on_close(self): - self.session.server.app.clients.remove(self) + self.app.ioloop.remove_timeout(self.timer) + self.app.clients.remove(self) def on_message(self, data): - self.session.server.app.input_queue.put(data + '\n') + self.app.input_queue.put(data + '\n') @@ -135,7 +149,7 @@ class Web(tornado.web.Application): encoding = 'utf-8') as f: self.config_template = json.load(f) - + self.ioloop = ioloop self.state = {} self.clients = [] -- 2.27.0