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

View File

@ -1,5 +1,9 @@
import Ember from "ember";
var INSECURE = 'ws://';
var SECURE = 'wss://';
var sockId = 1;
export default Ember.Object.extend(Ember.Evented, {
url: null,
socket: null,
@ -10,8 +14,7 @@ export default Ember.Object.extend(Ember.Evented, {
disconnectCb: null,
connect: function() {
var self = this;
var socket = self.get('socket');
var socket = this.get('socket');
if ( socket )
{
this.disconnect();
@ -19,71 +22,27 @@ export default Ember.Object.extend(Ember.Evented, {
var url = this.get('url');
// 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);
self.set('socket', socket);
socket.__sockId = id;
this.set('socket', socket);
socket.onmessage = function(event) {
Ember.run(function() {
self.trigger('message',event);
});
};
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'));
}
};
socket.onmessage = Ember.run.bind(this, this._message);
socket.onopen = Ember.run.bind(this, this._opened);
socket.onerror = Ember.run.bind(this, this._error);
socket.onclose = Ember.run.bind(this, this._closed);
},
disconnect: function(cb) {
var self = this;
//console.log('Socket disconnect');
this._log('disconnect');
if ( !this.get('connected') )
{
if ( cb )
@ -93,24 +52,95 @@ export default Ember.Object.extend(Ember.Evented, {
return;
}
this.set('connected', false);
this.set('autoReconnect',false);
if ( typeof cb === 'function' )
{
this.set('disconnectCb', cb);
}
this.setProperties({
'autoReconnect': false,
'disconnectCb': cb
});
var socket = this.get('socket');
if ( socket )
{
try {
this._log('closing');
socket.onopen = null;
socket.onerror = null;
socket.onmessage = null;
socket.close();
self.set('socket',null);
this.set('socket',null);
}
catch (e)
{
this._log('exception', e);
// 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()
}
if ( !req.upgrade )
if ( req.upgrade )
{
res.end();
}
else
{
res.writeHead(500, {'Content-Type': 'application/json'});
res.end(JSON.stringify(error));