Improve net/ documentation
This commit is contained in:
parent
084ddc8084
commit
2ae5d40463
|
@ -1,6 +1,9 @@
|
|||
/**
|
||||
* Networking base module. You should import some transport instead in
|
||||
* order to connect/accept connections to/from other nodes.
|
||||
* Networking base module. Defines base transport interface, useful for
|
||||
* implementing new transports. End-users should import some transport
|
||||
* instead in order to connect/accept connections to/from other nodes.
|
||||
* **NOTE**: `BaseTransport` is exported as a module.
|
||||
* @example var BaseTransport = require("bitmessage/net/base");
|
||||
* @module bitmessage/net/base
|
||||
*/
|
||||
// TODO(Kagami): Write some sort of tutorial.
|
||||
|
@ -13,7 +16,9 @@ var PPromise = require("../platform").Promise;
|
|||
var structs = require("../structs");
|
||||
|
||||
/**
|
||||
* Network transport base class.
|
||||
* Base transport class. Allows to use single class for both client and
|
||||
* server modes (as separate instances).
|
||||
* @param {?Object} opts - Transport options
|
||||
* @constructor
|
||||
* @static
|
||||
*/
|
||||
|
@ -25,8 +30,10 @@ inherits(BaseTransport, EventEmitter);
|
|||
|
||||
/**
|
||||
* Do the transport-specific bootstrap process and return promise that
|
||||
* contains discovered nodes when fulfilled.
|
||||
* @return {Promise.<Array.>}
|
||||
* contains discovered nodes when fulfilled (both modes).
|
||||
* NOTE: Do not use nodes received by this method in `addr` messages!
|
||||
* This is meaningless.
|
||||
* @return {Promise.<Array>}
|
||||
* @abstract
|
||||
*/
|
||||
BaseTransport.prototype.bootstrap = function() {
|
||||
|
@ -34,9 +41,9 @@ BaseTransport.prototype.bootstrap = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* Connect to the transport-specific address.
|
||||
* Should emit `open` event after successful connect and `established`
|
||||
* event after `verack` messages exchange.
|
||||
* Connect to the transport-specific address. Enters client mode. Should
|
||||
* emit `open` event after successful connect and `established` event
|
||||
* after `verack` messages exchange.
|
||||
* @abstract
|
||||
*/
|
||||
BaseTransport.prototype.connect = function() {
|
||||
|
@ -44,9 +51,9 @@ BaseTransport.prototype.connect = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* Listen for the transport-specific incoming connections.
|
||||
* Should emit `connection` event with a transport instance for each new
|
||||
* connection.
|
||||
* Listen for the transport-specific incoming connections. Enters server
|
||||
* mode. Should emit `connection` event with a transport instance for
|
||||
* each new connection.
|
||||
* @abstract
|
||||
*/
|
||||
BaseTransport.prototype.listen = function() {
|
||||
|
@ -55,9 +62,9 @@ BaseTransport.prototype.listen = function() {
|
|||
|
||||
/**
|
||||
* Send [message]{@link module:bitmessage/structs.message} over the
|
||||
* wire (client mode).
|
||||
* wire (client mode only).
|
||||
* @param {(Buffer|string)} msg - Encoded message or command string
|
||||
* @param (?Buffer} payload - Message payload (used if the first
|
||||
* @param {?Buffer} payload - Message payload (used if the first
|
||||
* argument is a string)
|
||||
* @abstract
|
||||
*/
|
||||
|
@ -67,9 +74,9 @@ BaseTransport.prototype.send = function() {
|
|||
|
||||
/**
|
||||
* Send [message]{@link module:bitmessage/structs.message} to all
|
||||
* connected clients (server mode).
|
||||
* connected clients (server mode only).
|
||||
* @param {(Buffer|string)} msg - Encoded message or command string
|
||||
* @param (?Buffer} payload - Message payload (used if the first
|
||||
* @param {?Buffer} payload - Message payload (used if the first
|
||||
* argument is a string)
|
||||
* @abstract
|
||||
*/
|
||||
|
@ -78,14 +85,14 @@ BaseTransport.prototype.broadcast = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* Close connection(s) and/or stop listening.
|
||||
* Close connection(s) and/or stop listening (both modes).
|
||||
* @abstract
|
||||
*/
|
||||
BaseTransport.prototype.close = function() {
|
||||
throw new Error("Not implemented");
|
||||
};
|
||||
|
||||
// Static helpers.
|
||||
// Static private helpers.
|
||||
|
||||
BaseTransport._getmsg = function(args) {
|
||||
if (typeof args[0] === "string") {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/**
|
||||
* TCP transport. Should be compatible with PyBitmessage. Available only
|
||||
* for Node.js.
|
||||
* TCP transport compatible with PyBitmessage. Available only for Node
|
||||
* platform.
|
||||
* **NOTE**: `TcpTransport` is exported as a module.
|
||||
* @example var TcpTransport = require("bitmessage/net/tcp");
|
||||
* @module bitmessage/net/tcp
|
||||
*/
|
||||
|
||||
|
@ -20,25 +22,26 @@ var getmsg = BaseTransport._getmsg;
|
|||
var unmap = BaseTransport._unmap;
|
||||
|
||||
/**
|
||||
* TCP transport constructor.
|
||||
* TCP transport class. Implements
|
||||
* [base transport interface]{@link module:bitmessage/net/base.BaseTransport}.
|
||||
* @constructor
|
||||
* @static
|
||||
*/
|
||||
function Transport(opts) {
|
||||
Transport.super_.call(this);
|
||||
function TcpTransport(opts) {
|
||||
TcpTransport.super_.call(this);
|
||||
objectAssign(this, opts);
|
||||
this.seeds = this.seeds || [];
|
||||
this.dnsSeeds = this.dnsSeeds || [];
|
||||
this._clients = {};
|
||||
}
|
||||
|
||||
inherits(Transport, BaseTransport);
|
||||
inherits(TcpTransport, BaseTransport);
|
||||
|
||||
function getfrom(client) {
|
||||
return unmap(client.remoteAddress) + ":" + client.remotePort;
|
||||
}
|
||||
|
||||
Transport.prototype.sendVersion = function() {
|
||||
TcpTransport.prototype._sendVersion = function() {
|
||||
return this.send(messages.version.encode({
|
||||
services: this.services,
|
||||
userAgent: this.userAgent,
|
||||
|
@ -49,7 +52,7 @@ Transport.prototype.sendVersion = function() {
|
|||
}));
|
||||
};
|
||||
|
||||
Transport.prototype._setupClient = function(client, accepted) {
|
||||
TcpTransport.prototype._setupClient = function(client, accepted) {
|
||||
var self = this;
|
||||
self._client = client;
|
||||
var cache = Buffer(0);
|
||||
|
@ -68,7 +71,7 @@ Transport.prototype._setupClient = function(client, accepted) {
|
|||
// accepted sockets but let's be sure.
|
||||
if (!accepted) {
|
||||
self.emit("open");
|
||||
self.sendVersion();
|
||||
self._sendVersion();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -113,7 +116,7 @@ Transport.prototype._setupClient = function(client, accepted) {
|
|||
self.send("verack");
|
||||
verackSent = true;
|
||||
if (accepted) {
|
||||
self.sendVersion();
|
||||
self._sendVersion();
|
||||
} else if (verackReceived) {
|
||||
self.emit("established");
|
||||
}
|
||||
|
@ -176,7 +179,7 @@ function resolveDnsSeed(seed) {
|
|||
});
|
||||
}
|
||||
|
||||
Transport.prototype.bootstrap = function() {
|
||||
TcpTransport.prototype.bootstrap = function() {
|
||||
var promises = this.dnsSeeds.map(resolveDnsSeed);
|
||||
var hardcodedNodes = this.seeds;
|
||||
// FIXME(Kagami): Filter incorrect/private IP range nodes?
|
||||
|
@ -190,13 +193,22 @@ Transport.prototype.bootstrap = function() {
|
|||
});
|
||||
};
|
||||
|
||||
Transport.prototype.connect = function() {
|
||||
/**
|
||||
* Connect to a TCP node. Connection arguments are the same as for
|
||||
* [net.connect](http://nodejs.org/api/net.html#net_net_connect_port_host_connectlistener).
|
||||
*/
|
||||
TcpTransport.prototype.connect = function() {
|
||||
assert(!this._client, "Already connected");
|
||||
assert(!this._server, "Already listening");
|
||||
this._setupClient(net.connect.apply(null, arguments));
|
||||
};
|
||||
|
||||
Transport.prototype.listen = function() {
|
||||
/**
|
||||
* Listen for incoming TCP connections. Listen arguments are the same as
|
||||
* for
|
||||
* [server.listen](http://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback).
|
||||
*/
|
||||
TcpTransport.prototype.listen = function() {
|
||||
assert(!this._client, "Already connected");
|
||||
assert(!this._server, "Already listening");
|
||||
|
||||
|
@ -241,7 +253,7 @@ Transport.prototype.listen = function() {
|
|||
});
|
||||
};
|
||||
|
||||
Transport.prototype.send = function() {
|
||||
TcpTransport.prototype.send = function() {
|
||||
if (this._client) {
|
||||
this._client.write(getmsg(arguments));
|
||||
} else {
|
||||
|
@ -249,7 +261,7 @@ Transport.prototype.send = function() {
|
|||
}
|
||||
};
|
||||
|
||||
Transport.prototype.broadcast = function() {
|
||||
TcpTransport.prototype.broadcast = function() {
|
||||
var data = getmsg(arguments);
|
||||
if (this._server) {
|
||||
Object.keys(this._clients).forEach(function(ip) {
|
||||
|
@ -260,7 +272,7 @@ Transport.prototype.broadcast = function() {
|
|||
}
|
||||
};
|
||||
|
||||
Transport.prototype.close = function() {
|
||||
TcpTransport.prototype.close = function() {
|
||||
if (this._client) {
|
||||
this._client.end();
|
||||
} else if (this._server) {
|
||||
|
@ -271,4 +283,4 @@ Transport.prototype.close = function() {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports = Transport;
|
||||
module.exports = TcpTransport;
|
||||
|
|
|
@ -12,19 +12,19 @@ var structs = require("../structs");
|
|||
var messages = require("../messages");
|
||||
var BaseTransport = require("./base");
|
||||
|
||||
function Transport(opts) {
|
||||
Transport.super_.call(this);
|
||||
function WsTransport(opts) {
|
||||
WsTransport.super_.call(this);
|
||||
objectAssign(this, opts);
|
||||
this.seeds = this.seeds || [];
|
||||
}
|
||||
|
||||
inherits(Transport, BaseTransport);
|
||||
inherits(WsTransport, BaseTransport);
|
||||
|
||||
Transport.prototype.bootstrap = function() {
|
||||
WsTransport.prototype.bootstrap = function() {
|
||||
return Promise.resolve([].concat(this.seeds));
|
||||
};
|
||||
|
||||
Transport.prototype.connect = function(url, protocols) {
|
||||
WsTransport.prototype.connect = function(url, protocols) {
|
||||
var self = this;
|
||||
assert(!self._client, "Already connected");
|
||||
|
||||
|
@ -95,7 +95,7 @@ Transport.prototype.connect = function(url, protocols) {
|
|||
};
|
||||
};
|
||||
|
||||
Transport.prototype.send = function() {
|
||||
WsTransport.prototype.send = function() {
|
||||
if (this._client) {
|
||||
this._client.send(BaseTransport._getmsg(arguments));
|
||||
} else {
|
||||
|
@ -103,10 +103,10 @@ Transport.prototype.send = function() {
|
|||
}
|
||||
};
|
||||
|
||||
Transport.prototype.close = function() {
|
||||
WsTransport.prototype.close = function() {
|
||||
if (this._client) {
|
||||
this._client.close();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Transport;
|
||||
module.exports = WsTransport;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/**
|
||||
* WebSocket transport. Needed because browsers can't handle TCP sockets
|
||||
* so we use separate WebSocket server to proxy messages into TCP data
|
||||
* packets.
|
||||
* packets. Available for both Node.js and Browser platforms.
|
||||
* **NOTE**: `WsTransport` is exported as a module.
|
||||
* @example var WsTransport = require("bitmessage/net/ws");
|
||||
* @module bitmessage/net/ws
|
||||
*/
|
||||
|
||||
|
@ -21,23 +23,24 @@ var getmsg = BaseTransport._getmsg;
|
|||
var unmap = BaseTransport._unmap;
|
||||
|
||||
/**
|
||||
* WebSocket transport constructor.
|
||||
* WebSocket transport class. Implements
|
||||
* [base transport interface]{@link module:bitmessage/net/base.BaseTransport}.
|
||||
* @constructor
|
||||
* @static
|
||||
*/
|
||||
function Transport(opts) {
|
||||
Transport.super_.call(this);
|
||||
function WsTransport(opts) {
|
||||
WsTransport.super_.call(this);
|
||||
objectAssign(this, opts);
|
||||
this.seeds = this.seeds || [];
|
||||
}
|
||||
|
||||
inherits(Transport, BaseTransport);
|
||||
inherits(WsTransport, BaseTransport);
|
||||
|
||||
function getfrom(client) {
|
||||
return unmap(client._socket.remoteAddress) + ":" + client._socket.remotePort;
|
||||
}
|
||||
|
||||
Transport.prototype.sendVersion = function() {
|
||||
WsTransport.prototype._sendVersion = function() {
|
||||
return this.send(messages.version.encode({
|
||||
services: this.services,
|
||||
userAgent: this.userAgent,
|
||||
|
@ -48,7 +51,7 @@ Transport.prototype.sendVersion = function() {
|
|||
}));
|
||||
};
|
||||
|
||||
Transport.prototype._handleTimeout = function() {
|
||||
WsTransport.prototype._handleTimeout = function() {
|
||||
var client = this._client;
|
||||
// TODO(Kagami): We may also want to close connection if it wasn't
|
||||
// established within minute.
|
||||
|
@ -63,7 +66,7 @@ Transport.prototype._handleTimeout = function() {
|
|||
});
|
||||
};
|
||||
|
||||
Transport.prototype._setupClient = function(client, accepted) {
|
||||
WsTransport.prototype._setupClient = function(client, accepted) {
|
||||
var self = this;
|
||||
self._client = client;
|
||||
var verackSent = false;
|
||||
|
@ -79,7 +82,7 @@ Transport.prototype._setupClient = function(client, accepted) {
|
|||
// `_setupClient` is called.
|
||||
self._handleTimeout();
|
||||
self.emit("open");
|
||||
self.sendVersion();
|
||||
self._sendVersion();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -113,7 +116,7 @@ Transport.prototype._setupClient = function(client, accepted) {
|
|||
self.send("verack");
|
||||
verackSent = true;
|
||||
if (accepted) {
|
||||
self.sendVersion();
|
||||
self._sendVersion();
|
||||
} else if (verackReceived) {
|
||||
established = true;
|
||||
self.emit("established");
|
||||
|
@ -138,11 +141,15 @@ Transport.prototype._setupClient = function(client, accepted) {
|
|||
});
|
||||
};
|
||||
|
||||
Transport.prototype.bootstrap = function() {
|
||||
WsTransport.prototype.bootstrap = function() {
|
||||
return PPromise.resolve([].concat(this.seeds));
|
||||
};
|
||||
|
||||
Transport.prototype.connect = function(address, protocols, options) {
|
||||
/**
|
||||
* Connect to a WebSocket node. Connection arguments are the same as for
|
||||
* [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket).
|
||||
*/
|
||||
WsTransport.prototype.connect = function(address, protocols, options) {
|
||||
assert(!this._client, "Already connected");
|
||||
assert(!this._server, "Already listening");
|
||||
// `new` doesn't work with `apply`, so passing all possible arguments
|
||||
|
@ -150,7 +157,13 @@ Transport.prototype.connect = function(address, protocols, options) {
|
|||
this._setupClient(new WebSocket(address, protocols, options));
|
||||
};
|
||||
|
||||
Transport.prototype.listen = function(options, callback) {
|
||||
/**
|
||||
* Listen for incoming WebSocket connections. Listen arguments are the
|
||||
* same as for
|
||||
* [WebSocketServer](https://github.com/websockets/ws#server-example).
|
||||
* Available only for Node platform.
|
||||
*/
|
||||
WsTransport.prototype.listen = function(options, callback) {
|
||||
assert(!this._client, "Already connected");
|
||||
assert(!this._server, "Already listening");
|
||||
|
||||
|
@ -195,7 +208,7 @@ Transport.prototype.listen = function(options, callback) {
|
|||
});
|
||||
};
|
||||
|
||||
Transport.prototype.send = function() {
|
||||
WsTransport.prototype.send = function() {
|
||||
if (this._client) {
|
||||
// TODO(Kagami): `mask: true` doesn't work with Chromium 40. File a
|
||||
// bug to ws bugtracker.
|
||||
|
@ -205,7 +218,7 @@ Transport.prototype.send = function() {
|
|||
}
|
||||
};
|
||||
|
||||
Transport.prototype.broadcast = function() {
|
||||
WsTransport.prototype.broadcast = function() {
|
||||
var data = getmsg(arguments);
|
||||
if (this._server) {
|
||||
this._server.clients.forEach(function(client) {
|
||||
|
@ -216,7 +229,7 @@ Transport.prototype.broadcast = function() {
|
|||
}
|
||||
};
|
||||
|
||||
Transport.prototype.close = function() {
|
||||
WsTransport.prototype.close = function() {
|
||||
if (this._client) {
|
||||
this._client.close();
|
||||
} else if (this._server) {
|
||||
|
@ -227,4 +240,4 @@ Transport.prototype.close = function() {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports = Transport;
|
||||
module.exports = WsTransport;
|
||||
|
|
Loading…
Reference in New Issue
Block a user