sockets now autoreconnect after disconnection

This commit is contained in:
Manuel Araoz 2014-02-13 16:24:17 -03:00
parent 6877cbb86c
commit 42c193dfd5
6 changed files with 196 additions and 182 deletions

View File

@ -10,6 +10,7 @@ module.exports.init = function(app, io_ext) {
ios.set('log level', 1); // reduce logging ios.set('log level', 1); // reduce logging
ios.sockets.on('connection', function(socket) { ios.sockets.on('connection', function(socket) {
socket.on('subscribe', function(topic) { socket.on('subscribe', function(topic) {
console.log('someone subscribed to ' + topic);
socket.join(topic); socket.join(topic);
}); });
}); });
@ -19,33 +20,35 @@ module.exports.broadcastTx = function(tx) {
if (ios) { if (ios) {
var t = {}; var t = {};
if (typeof tx === 'string') { if (typeof tx === 'string') {
t = { txid: tx }; t = {
} txid: tx
else { };
} else {
t = tx; t = tx;
// Outputs // Outputs
var valueOut = 0; var valueOut = 0;
t.vout.forEach( function(o) { t.vout.forEach(function(o) {
valueOut += o.value * util.COIN; valueOut += o.value * util.COIN;
}); });
t.valueOut = parseInt(valueOut) / util.COIN; t.valueOut = parseInt(valueOut) / util.COIN;
} }
ios.sockets.in('inv').emit('tx', t); ios.sockets. in ('inv').emit('tx', t);
} }
}; };
module.exports.broadcastBlock = function(block) { module.exports.broadcastBlock = function(block) {
if (ios) ios.sockets.in('inv').emit('block', block); if (ios) ios.sockets. in ('inv').emit('block', block);
}; };
module.exports.broadcastAddressTx = function(address, tx) { module.exports.broadcastAddressTx = function(address, tx) {
if (ios) ios.sockets.in(address).emit(address, tx); console.log('bcatx = '+address+' '+tx);
if (ios) ios.sockets. in (address).emit(address, tx);
}; };
module.exports.broadcastSyncInfo = function(historicSync) { module.exports.broadcastSyncInfo = function(historicSync) {
if (ios) { if (ios) {
ios.sockets.in('sync').emit('status', historicSync); ios.sockets. in ('sync').emit('status', historicSync);
} }
}; };

View File

@ -1,41 +1,41 @@
'use strict'; 'use strict';
angular.module('insight.address').controller('AddressController', angular.module('insight.address').controller('AddressController',
function($scope, $rootScope, $routeParams, $location, Global, Address, getSocket) { function($scope, $rootScope, $routeParams, $location, Global, Address, getSocket) {
$scope.global = Global; $scope.global = Global;
$scope.findOne = function() { $scope.findOne = function() {
$rootScope.currentAddr = $routeParams.addrStr; $rootScope.currentAddr = $routeParams.addrStr;
Address.get({ Address.get({
addrStr: $routeParams.addrStr addrStr: $routeParams.addrStr
}, },
function(address) { function(address) {
$rootScope.titleDetail = address.addrStr.substring(0,7) + '...'; $rootScope.titleDetail = address.addrStr.substring(0, 7) + '...';
$rootScope.flashMessage = null; $rootScope.flashMessage = null;
$scope.address = address; $scope.address = address;
}, },
function(e) { function(e) {
if (e.status === 400) { if (e.status === 400) {
$rootScope.flashMessage = 'Invalid Address: ' + $routeParams.addrStr; $rootScope.flashMessage = 'Invalid Address: ' + $routeParams.addrStr;
} } else if (e.status === 503) {
else if (e.status === 503) { $rootScope.flashMessage = 'Backend Error. ' + e.data;
$rootScope.flashMessage = 'Backend Error. ' + e.data; } else {
} $rootScope.flashMessage = 'Address Not Found';
else { }
$rootScope.flashMessage = 'Address Not Found'; $location.path('/');
} });
$location.path('/'); };
var socket = getSocket($scope);
socket.on('connect', function() {
socket.emit('subscribe', $routeParams.addrStr);
socket.on($routeParams.addrStr, function(tx) {
console.log('AddressTx event received ' + tx);
$rootScope.$broadcast('tx', tx);
});
}); });
};
var socket = getSocket($scope); $scope.params = $routeParams;
socket.emit('subscribe', $routeParams.addrStr);
socket.on($routeParams.addrStr, function(tx) {
console.log('AddressTx event received ' + tx);
$rootScope.$broadcast('tx', tx);
}); });
$scope.params = $routeParams;
});

View File

@ -2,41 +2,39 @@
angular.module('insight.system').controller('HeaderController', angular.module('insight.system').controller('HeaderController',
function($scope, $rootScope, getSocket, Global, Block) { function($scope, $rootScope, getSocket, Global, Block) {
$scope.global = Global; $scope.global = Global;
$rootScope.currency = { $rootScope.currency = {
factor: 1, factor: 1,
bitstamp: 0, bitstamp: 0,
symbol: 'BTC' symbol: 'BTC'
}; };
$scope.menu = [ $scope.menu = [{
{
'title': 'Blocks', 'title': 'Blocks',
'link': 'blocks' 'link': 'blocks'
}, }, {
{
'title': 'Status', 'title': 'Status',
'link': 'status' 'link': 'status'
} }];
];
var socket = getSocket($scope); var _getBlock = function(hash) {
socket.emit('subscribe', 'inv'); Block.get({
blockHash: hash
}, function(res) {
$scope.totalBlocks = res.height;
});
};
var _getBlock = function(hash) { var socket = getSocket($scope);
Block.get({ socket.on('connect', function() {
blockHash: hash socket.emit('subscribe', 'inv');
}, function(res) {
$scope.totalBlocks = res.height; socket.on('block', function(block) {
var blockHash = block.toString();
_getBlock(blockHash);
});
}); });
};
socket.on('block', function(block) { $rootScope.isCollapsed = true;
var blockHash = block.toString();
console.log('Updated Blocks Height!');
_getBlock(blockHash);
}); });
$rootScope.isCollapsed = true;
});

View File

@ -5,40 +5,43 @@ var BLOCKS_DISPLAYED = 5;
angular.module('insight.system').controller('IndexController', angular.module('insight.system').controller('IndexController',
function($scope, Global, getSocket, Blocks) { function($scope, Global, getSocket, Blocks) {
$scope.global = Global; $scope.global = Global;
var _getBlocks = function() {
Blocks.get({
limit: BLOCKS_DISPLAYED
}, function(res) {
$scope.blocks = res.blocks;
$scope.blocksLength = res.lenght;
});
};
var socket = getSocket($scope);
socket.on('connect', function() {
socket.emit('subscribe', 'inv');
socket.on('tx', function(tx) {
$scope.txs.unshift(tx);
if (parseInt($scope.txs.length, 10) >= parseInt(TRANSACTION_DISPLAYED, 10)) {
$scope.txs = $scope.txs.splice(0, TRANSACTION_DISPLAYED);
}
});
socket.on('block', function() {
_getBlocks();
});
var _getBlocks = function() {
Blocks.get({
limit: BLOCKS_DISPLAYED
}, function(res) {
$scope.blocks = res.blocks;
$scope.blocksLength = res.lenght;
}); });
};
var socket = getSocket($scope);
socket.emit('subscribe', 'inv');
socket.on('tx', function(tx) { $scope.humanSince = function(time) {
$scope.txs.unshift(tx); var m = moment.unix(time);
if (parseInt($scope.txs.length, 10) >= parseInt(TRANSACTION_DISPLAYED, 10)) { return m.max().fromNow();
$scope.txs = $scope.txs.splice(0, TRANSACTION_DISPLAYED); };
}
$scope.index = function() {
_getBlocks();
};
$scope.txs = [];
$scope.blocks = [];
}); });
socket.on('block', function() {
_getBlocks();
});
$scope.humanSince = function(time) {
var m = moment.unix(time);
return m.max().fromNow();
};
$scope.index = function() {
_getBlocks();
};
$scope.txs = [];
$scope.blocks = [];
});

View File

@ -1,41 +1,44 @@
'use strict'; 'use strict';
angular.module('insight.status').controller('StatusController', angular.module('insight.status').controller('StatusController',
function($scope, $routeParams, $location, Global, Status, Sync, getSocket) { function($scope, $routeParams, $location, Global, Status, Sync, getSocket) {
$scope.global = Global; $scope.global = Global;
$scope.getStatus = function(q) { $scope.getStatus = function(q) {
Status.get({ Status.get({
q: 'get' + q q: 'get' + q
}, },
function(d) { function(d) {
$scope.loaded = 1; $scope.loaded = 1;
angular.extend($scope, d); angular.extend($scope, d);
}, },
function(e) { function(e) {
$scope.error = 'API ERROR: ' + e.data; $scope.error = 'API ERROR: ' + e.data;
});
};
var _onSyncUpdate = function(sync) {
$scope.sync = sync;
};
$scope.getSync = function() {
Sync.get({},
function(sync) {
_onSyncUpdate(sync);
},
function(e) {
var err = 'Could not get sync information' + e.toString();
$scope.sync = {
error: err
};
});
};
var socket = getSocket($scope);
socket.on('connect', function() {
socket.emit('subscribe', 'sync');
socket.on('status', function(sync) {
_onSyncUpdate(sync);
});
}); });
};
var _onSyncUpdate = function(sync) {
$scope.sync = sync;
};
$scope.getSync = function() {
Sync.get({},
function(sync) {
_onSyncUpdate(sync);
},
function(e) {
var err = 'Could not get sync information' + e.toString();
$scope.sync = { error: err };
});
};
var socket = getSocket($scope);
socket.emit('subscribe', 'sync');
socket.on('status', function(sync) {
_onSyncUpdate(sync);
}); });
});

View File

@ -1,64 +1,71 @@
'use strict'; 'use strict';
var ScopedSocket = function(socket, $rootScope) { var ScopedSocket = function(socket, $rootScope) {
this.socket = socket; this.socket = socket;
this.$rootScope = $rootScope; this.$rootScope = $rootScope;
this.listeners = []; this.listeners = [];
}; };
ScopedSocket.prototype.removeAllListeners = function() { ScopedSocket.prototype.removeAllListeners = function(opts) {
for (var i = 0; i < this.listeners.length; i++) { if (!opts) opts = {};
var details = this.listeners[i]; for (var i = 0; i < this.listeners.length; i++) {
this.socket.removeListener(details.event, details.fn); var details = this.listeners[i];
} if (opts.skipConnect && details.event === 'connect') {
continue;
}
this.socket.removeListener(details.event, details.fn);
}
this.listeners = []; this.listeners = [];
}; };
ScopedSocket.prototype.on = function(event, callback) { ScopedSocket.prototype.on = function(event, callback) {
var socket = this.socket; var socket = this.socket;
var $rootScope = this.$rootScope; var $rootScope = this.$rootScope;
var wrapped_callback = function() { var wrapped_callback = function() {
var args = arguments; var args = arguments;
$rootScope.$apply(function() { $rootScope.$apply(function() {
callback.apply(socket, args); callback.apply(socket, args);
}); });
}; };
socket.on(event, wrapped_callback); socket.on(event, wrapped_callback);
this.listeners.push({ this.listeners.push({
event: event, event: event,
fn: wrapped_callback fn: wrapped_callback
}); });
}; };
ScopedSocket.prototype.emit = function(event, data, callback) { ScopedSocket.prototype.emit = function(event, data, callback) {
var socket = this.socket; var socket = this.socket;
var $rootScope = this.$rootScope; var $rootScope = this.$rootScope;
socket.emit(event, data, function() { socket.emit(event, data, function() {
var args = arguments; var args = arguments;
$rootScope.$apply(function() { $rootScope.$apply(function() {
if (callback) { if (callback) {
callback.apply(socket, args); callback.apply(socket, args);
} }
}); });
}); });
}; };
angular.module('insight.socket').factory('getSocket', angular.module('insight.socket').factory('getSocket',
function($rootScope) { function($rootScope) {
var socket = io.connect(null, { var socket = io.connect(null, {
'reconnect': true, 'reconnect': true,
'reconnection delay': 500, 'reconnection delay': 500,
});
return function(scope) {
var scopedSocket = new ScopedSocket(socket, $rootScope);
scope.$on('$routeChangeStart', function() {
}); });
scope.$on('$destroy', function() { return function(scope) {
scopedSocket.removeAllListeners(); var scopedSocket = new ScopedSocket(socket, $rootScope);
}); scope.$on('$destroy', function() {
return scopedSocket; scopedSocket.removeAllListeners();
}; });
}); socket.on('connect', function() {
scopedSocket.removeAllListeners({
skipConnect: true
});
});
return scopedSocket;
};
});