Web socket reconnect, logging, close improvements

This commit is contained in:
Vincent Fiduccia 2015-06-13 20:44:02 -07:00
parent 0745c8198d
commit c90c45c7bc
3 changed files with 121 additions and 103 deletions

View File

@ -7,6 +7,7 @@ import C from 'ui/utils/constants';
export default Ember.Route.extend(AuthenticatedRouteMixin, { export default Ember.Route.extend(AuthenticatedRouteMixin, {
socket: null, socket: null,
pingTimer: null,
model: function(params, transition) { model: function(params, transition) {
var store = this.get('store'); var store = this.get('store');
@ -220,13 +221,13 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
}, },
// Raw message from the WebSocket // Raw message from the WebSocket
//wsMessage: function(/*data*/) { //subscribeMessage: function(/*data*/) {
//console.log('wsMessage',data); //console.log('subscribeMessage',data);
//}, //},
// WebSocket connected // WebSocket connected
wsConnected: function(tries,msec) { subscribeConnected: function(tries,msec) {
var msg = 'WebSocket connected'; var msg = 'Subscribe connected';
if (tries > 0) if (tries > 0)
{ {
msg += ' (after '+ tries + ' ' + (tries === 1 ? 'try' : 'tries'); msg += ' (after '+ tries + ' ' + (tries === 1 ? 'try' : 'tries');
@ -241,37 +242,21 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
}, },
// WebSocket disconnected // WebSocket disconnected
wsDisconnected: function() { subscribeDisconnected: function() {
console.log('WebSocket disconnected'); console.log('Subscribe disconnected');
}, },
wsPing: function() { subscribePing: function() {
console.log('WebSocket ping'); console.log('Subscribe ping');
}, if ( this.get('pingTimer') )
/*
agentChanged: function(change) {
if (!change || !change.data || !change.data.resource)
{ {
return; Ember.run.cancel(this.get('pingTimer'));
} }
//console.log('Agent Changed:', change);
var agent = change.data.resource;
var id = agent.id;
delete agent.hosts;
var hosts = this.controllerFor('hosts'); this.set('pingTimer', Ember.run.later(this, function() {
hosts.forEach(function(host) { console.log('Subscribe missed 2 pings...');
if ( host.get('agent.id') === id ) this.get('socket').connect();
{ }, 11000));
host.get('agent').setProperties(agent);
}
});
},
*/
machineChanged: function(change) {
console.log('Machine changed:',change);
}, },
hostChanged: function(change) { hostChanged: function(change) {
@ -282,7 +267,6 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
{ {
machine.get('hosts').addObject(host); machine.get('hosts').addObject(host);
} }
console.log('Host changed:',change);
}, },
containerChanged: function(change) { containerChanged: function(change) {
@ -395,7 +379,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
socket.on('message', (event) => { socket.on('message', (event) => {
var d = JSON.parse(event.data, boundTypeify); var d = JSON.parse(event.data, boundTypeify);
//this._trySend('wsMessage',d); //this._trySend('subscribeMessage',d);
var str = d.name; var str = d.name;
if ( d.resourceType ) if ( d.resourceType )
@ -415,7 +399,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
} }
else if ( d.name === 'ping' ) else if ( d.name === 'ping' )
{ {
action = 'wsPing'; action = 'subscribePing';
} }
if ( action ) if ( action )
@ -425,11 +409,11 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
}); });
socket.on('connected', (tries, after) => { socket.on('connected', (tries, after) => {
this._trySend('wsConnected', tries, after); this._trySend('subscribeConnected', tries, after);
}); });
socket.on('disconnected', () => { socket.on('disconnected', () => {
this._trySend('wsDisconnected', this.get('tries')); this._trySend('subscribeDisconnected', this.get('tries'));
}); });
this.set('socket', socket); this.set('socket', socket);

View File

@ -1,5 +1,9 @@
import Ember from "ember"; import Ember from "ember";
var INSECURE = 'ws://';
var SECURE = 'wss://';
var sockId = 1;
export default Ember.Object.extend(Ember.Evented, { export default Ember.Object.extend(Ember.Evented, {
url: null, url: null,
socket: null, socket: null,
@ -10,8 +14,7 @@ export default Ember.Object.extend(Ember.Evented, {
disconnectCb: null, disconnectCb: null,
connect: function() { connect: function() {
var self = this; var socket = this.get('socket');
var socket = self.get('socket');
if ( socket ) if ( socket )
{ {
this.disconnect(); this.disconnect();
@ -19,71 +22,27 @@ export default Ember.Object.extend(Ember.Evented, {
var url = this.get('url'); var url = this.get('url');
// If the site is SSL, the WebSocket should be too... // If the site is SSL, the WebSocket should be too...
if ( window.location.protocol === 'https:' && url.indexOf('ws://') === 0 ) if ( window.location.protocol === 'https:' && url.indexOf(INSECURE) === 0 )
{ {
url = 'wss://' + url.substr(5); url = SECURE + url.substr(INSECURE.length);
} }
console.log('Socket connect to',url); var id = sockId++;
console.log('Socket connect',id,'to', url.replace(/\?.*/,'')+'...');
socket = new WebSocket(url); socket = new WebSocket(url);
self.set('socket', socket); socket.__sockId = id;
this.set('socket', socket);
socket.onmessage = function(event) { socket.onmessage = Ember.run.bind(this, this._message);
Ember.run(function() { socket.onopen = Ember.run.bind(this, this._opened);
self.trigger('message',event); socket.onerror = Ember.run.bind(this, this._error);
}); socket.onclose = Ember.run.bind(this, this._closed);
};
socket.onopen = function() {
//console.log('Socket Open');
var now = (new Date()).getTime();
self.set('connected',true);
var at = self.get('disconnectedAt');
var after = null;
if ( at )
{
after = now - at;
}
self.trigger('connected', self.get('tries'), after);
self.set('tries',0);
self.set('disconnectedAt', null);
};
socket.onclose = function() {
//console.log('Socket Closed');
var wasConnected = self.get('connected');
self.set('connected',false);
self.incrementProperty('tries');
if ( self.get('disconnectedAt') === null )
{
self.set('disconnectedAt', (new Date()).getTime());
}
socket.close();
if ( wasConnected && self.get('autoReconnect') )
{
var delay = Math.max(1000, Math.min(1000 * self.get('tries'), 30000));
setTimeout(self.connect.bind(self), delay);
}
if ( self.get('disconnectCb') )
{
self.get('disconnectCb')();
}
else
{
self.trigger('disconnected', self.get('tries'));
}
};
}, },
disconnect: function(cb) { disconnect: function(cb) {
var self = this; this._log('disconnect');
//console.log('Socket disconnect');
if ( !this.get('connected') ) if ( !this.get('connected') )
{ {
if ( cb ) if ( cb )
@ -93,24 +52,95 @@ export default Ember.Object.extend(Ember.Evented, {
return; return;
} }
this.set('connected', false); this.setProperties({
this.set('autoReconnect',false); 'autoReconnect': false,
if ( typeof cb === 'function' ) 'disconnectCb': cb
{ });
this.set('disconnectCb', cb);
}
var socket = this.get('socket'); var socket = this.get('socket');
if ( socket ) if ( socket )
{ {
try { try {
this._log('closing');
socket.onopen = null;
socket.onerror = null;
socket.onmessage = null;
socket.close(); socket.close();
self.set('socket',null); this.set('socket',null);
} }
catch (e) catch (e)
{ {
this._log('exception', e);
// Meh.. // Meh..
} }
} }
} },
_opened: function() {
this._log('opened');
var now = (new Date()).getTime();
var at = this.get('disconnectedAt');
var after = null;
if ( at )
{
after = now - at;
}
this.setProperties({
connected: true,
tries: 0,
disconnectedAt: null,
});
this.trigger('connected', this.get('tries'), after);
},
_message: function(event) {
this.trigger('message',event);
},
_error: function() {
this._log('error');
this.disconnect();
},
_closed: function() {
console.log('Socket closed');
var wasConnected = this.get('connected');
this.set('connected',false);
this.incrementProperty('tries');
if ( this.get('disconnectedAt') === null )
{
this.set('disconnectedAt', (new Date()).getTime());
}
if ( wasConnected && this.get('autoReconnect') )
{
var delay = Math.max(1000, Math.min(1000 * this.get('tries'), 30000));
Ember.run.later(this, this.connect, delay);
}
if ( typeof this.get('disconnectCb') === 'function' )
{
this.get('disconnectCb')();
}
if ( wasConnected )
{
this.trigger('disconnected');
}
},
_log: function(/*arguments*/) {
var args = ['Socket', this.get('socket.__sockId') ];
for ( var i = 0 ; i < arguments.length ; i++ )
{
args.push(arguments[i]);
}
console.log.apply(console, args);
},
}); });

View File

@ -75,7 +75,11 @@ module.exports = function(app, options) {
detail: err.toString() detail: err.toString()
} }
if ( !req.upgrade ) if ( req.upgrade )
{
res.end();
}
else
{ {
res.writeHead(500, {'Content-Type': 'application/json'}); res.writeHead(500, {'Content-Type': 'application/json'});
res.end(JSON.stringify(error)); res.end(JSON.stringify(error));