refactor websocket api.

This commit is contained in:
Christopher Jeffrey 2016-07-14 16:53:13 -07:00
parent ba4ce73a8d
commit 74c999abe3
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 112 additions and 38 deletions

View File

@ -89,7 +89,7 @@ HTTPClient.prototype._open = function _open(callback) {
self.emit('error', new Error('Wrong network.'));
});
this.socket.on('tx', function(tx, map) {
this.socket.on('wallet tx', function(tx, map) {
try {
tx = bcoin.tx.fromJSON(tx);
} catch (e) {
@ -98,7 +98,7 @@ HTTPClient.prototype._open = function _open(callback) {
self.emit('tx', tx, map);
});
this.socket.on('confirmed', function(tx, map) {
this.socket.on('wallet confirmed', function(tx, map) {
try {
tx = bcoin.tx.fromJSON(tx);
} catch (e) {
@ -107,7 +107,7 @@ HTTPClient.prototype._open = function _open(callback) {
self.emit('confirmed', tx, map);
});
this.socket.on('updated', function(tx, map) {
this.socket.on('wallet updated', function(tx, map) {
try {
tx = bcoin.tx.fromJSON(tx);
} catch (e) {
@ -116,7 +116,7 @@ HTTPClient.prototype._open = function _open(callback) {
self.emit('updated', tx, map);
});
this.socket.on('address', function(receive, change, map) {
this.socket.on('wallet address', function(receive, change, map) {
receive = receive.map(function(address) {
return bcoin.keyring.fromJSON(address);
});
@ -126,7 +126,7 @@ HTTPClient.prototype._open = function _open(callback) {
self.emit('address', receive, change, map);
});
this.socket.on('balance', function(balance, id) {
this.socket.on('wallet balance', function(balance, id) {
self.emit('balance', {
confirmed: utils.satoshi(balance.confirmed),
unconfirmed: utils.satoshi(balance.unconfirmed),
@ -134,7 +134,7 @@ HTTPClient.prototype._open = function _open(callback) {
}, id);
});
this.socket.on('balances', function(json) {
this.socket.on('wallet balances', function(json) {
var balances = {};
Object.keys(json).forEach(function(id) {
balances[id] = {
@ -147,7 +147,11 @@ HTTPClient.prototype._open = function _open(callback) {
});
this.socket.on('connect', function() {
callback();
self.socket.emit('auth', self.apiKey.toString('hex'), function(err) {
if (err)
return callback(new Error(err.error));
callback();
});
});
};
@ -172,11 +176,11 @@ HTTPClient.prototype._close = function close(callback) {
* @param {WalletID} id
*/
HTTPClient.prototype.join = function join(id, token) {
HTTPClient.prototype.join = function join(id, token, callback) {
if (!this.socket)
return;
return callback();
this.socket.emit('join', id, token);
this.socket.emit('wallet join', id, token, callback);
};
/**
@ -184,11 +188,11 @@ HTTPClient.prototype.join = function join(id, token) {
* @param {WalletID} id
*/
HTTPClient.prototype.leave = function leave(id) {
HTTPClient.prototype.leave = function leave(id, callback) {
if (!this.socket)
return;
this.socket.emit('leave', id);
this.socket.emit('wallet leave', id, callback);
};
/**

View File

@ -830,34 +830,69 @@ HTTPServer.prototype._initIO = function _initIO() {
return;
this.server.on('websocket', function(socket) {
socket.bcoin = new ClientSocket(self, socket);
socket.bcoin.startTimeout();
socket.on('error', function(err) {
self.emit('error', err);
});
socket.on('join', function(id, token) {
socket.on('auth', function(apiKey, callback) {
callback = utils.ensure(callback);
if (!self.apiKey) {
self.logger.info('Successful auth.');
socket.bcoin.stopTimeout();
self.emit('websocket', socket);
return callback();
}
if (!utils.isHex(apiKey))
return callback({ error: 'Bad key.' });
apiKey = new Buffer(apiKey, 'hex');
if (!utils.ccmp(apiKey, self.apiKey))
return callback({ error: 'Bad key.' });
self.logger.info('Successful auth.');
socket.bcoin.stopTimeout();
self.emit('websocket', socket);
return callback();
});
socket.emit('version', {
version: constants.USER_VERSION,
agent: constants.USER_AGENT,
network: self.network.type
});
});
this.on('websocket', function(socket) {
socket.on('wallet join', function(id, token, callback) {
callback = utils.ensure(callback);
if (!self.options.walletAuth) {
socket.join(id);
return;
return callback();
}
self.walletdb.auth(id, token, function(err) {
if (err) {
self.logger.info('Auth failure for %s: %s.', id, err.message);
return;
self.logger.info('Wallet auth failure for %s: %s.', id, err.message);
return callback({ error: 'Bad token.' });
}
self.logger.info('Successful auth for %s.', id);
self.logger.info('Successful wallet auth for %s.', id);
socket.join(id);
return callback();
});
});
socket.on('leave', function(id) {
socket.on('wallet leave', function(id, callback) {
callback = utils.ensure(callback);
socket.leave(id);
});
self.emit('websocket', socket);
socket.emit('version', {
version: constants.USER_AGENT,
network: self.network.type
return callback();
});
});
@ -865,27 +900,27 @@ HTTPServer.prototype._initIO = function _initIO() {
var summary = map.toJSON();
tx = tx.toJSON();
map.getWallets().forEach(function(id) {
self.server.io.to(id).emit('tx', tx, summary);
self.server.io.to(id).emit('wallet tx', tx, summary);
});
self.server.io.to('!all').emit('tx', tx, summary);
self.server.io.to('!all').emit('wallet tx', tx, summary);
});
this.walletdb.on('confirmed', function(tx, map) {
var summary = map.toJSON();
tx = tx.toJSON();
map.getWallets().forEach(function(id) {
self.server.io.to(id).emit('confirmed', tx, summary);
self.server.io.to(id).emit('wallet confirmed', tx, summary);
});
self.server.io.to('!all').emit('confirmed', tx, summary);
self.server.io.to('!all').emit('wallet confirmed', tx, summary);
});
this.walletdb.on('updated', function(tx, map) {
var summary = map.toJSON();
tx = tx.toJSON();
map.getWallets().forEach(function(id) {
self.server.io.to(id).emit('updated', tx, summary);
self.server.io.to(id).emit('wallet updated', tx, summary);
});
self.server.io.to('!all').emit('updated', tx, summary);
self.server.io.to('!all').emit('wallet updated', tx, summary);
});
this.walletdb.on('balances', function(balances) {
@ -896,10 +931,10 @@ HTTPServer.prototype._initIO = function _initIO() {
unconfirmed: utils.btc(balances[id].unconfirmed),
total: utils.btc(balances[id].total)
};
self.server.io.to(id).emit('balance', json[id], id);
self.server.io.to('!all').emit('balance', json[id], id);
self.server.io.to(id).emit('wallet balance', json[id], id);
self.server.io.to('!all').emit('wallet balance', json[id], id);
});
self.server.io.to('!all').emit('balances', json);
self.server.io.to('!all').emit('wallet balances', json);
});
this.walletdb.on('address', function(receive, change, map) {
@ -914,10 +949,10 @@ HTTPServer.prototype._initIO = function _initIO() {
});
map.getWallets().forEach(function(id) {
self.server.io.to(id).emit('address', receive, change, summary);
self.server.io.to(id).emit('wallet address', receive, change, summary);
});
self.server.io.to('!all').emit('address', receive, change, summary);
self.server.io.to('!all').emit('wallet address', receive, change, summary);
});
};
@ -1003,6 +1038,38 @@ HTTPServer.prototype.listen = function listen(port, host, callback) {
});
};
/**
* ClientSocket
* @constructor
* @param {HTTPServer} server
* @param {SocketIO.Socket}
*/
function ClientSocket(server, socket) {
this.server = server;
this.socket = socket;
this.timeout = null;
}
ClientSocket.prototype.startTimeout = function startTimeout() {
var self = this;
this.stopTimeout();
this.timeout = setTimeout(function() {
self.destroy();
}, 60000);
};
ClientSocket.prototype.stopTimeout = function stopTimeout() {
if (this.timeout != null) {
clearTimeout(this.timeout);
this.timeout = null;
}
};
ClientSocket.prototype.destroy = function() {
this.socket.disconnect();
};
/*
* Expose
*/

View File

@ -114,8 +114,11 @@ HTTPWallet.prototype.open = function open(options, callback) {
self.id = wallet.id;
self.client.auth = { username: 'x', password: wallet.token };
self.token = new Buffer(wallet.token, 'hex');
self.client.join(self.id, wallet.token);
callback(null, wallet);
self.client.join(self.id, wallet.token, function(err) {
if (err)
return callback(new Error(err.error));
callback(null, wallet);
});
});
});
};