Net improvements
This commit is contained in:
parent
49e4aa4158
commit
e52e226662
|
@ -91,7 +91,7 @@ TcpTransport.prototype._sendVersion = function() {
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
TcpTransport.prototype._setupClient = function(client, accepted) {
|
TcpTransport.prototype._setupClient = function(client, incoming) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self._client = client;
|
self._client = client;
|
||||||
var cache = Buffer(0);
|
var cache = Buffer(0);
|
||||||
|
@ -107,8 +107,8 @@ TcpTransport.prototype._setupClient = function(client, accepted) {
|
||||||
|
|
||||||
client.on("connect", function() {
|
client.on("connect", function() {
|
||||||
// NOTE(Kagami): This handler shouldn't be called at all for
|
// NOTE(Kagami): This handler shouldn't be called at all for
|
||||||
// accepted sockets but let's be sure.
|
// incoming connections but let's be sure.
|
||||||
if (!accepted) {
|
if (!incoming) {
|
||||||
self.emit("open");
|
self.emit("open");
|
||||||
self._sendVersion();
|
self._sendVersion();
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ TcpTransport.prototype._setupClient = function(client, accepted) {
|
||||||
}
|
}
|
||||||
self.send("verack");
|
self.send("verack");
|
||||||
verackSent = true;
|
verackSent = true;
|
||||||
if (accepted) {
|
if (incoming) {
|
||||||
self._sendVersion();
|
self._sendVersion();
|
||||||
} else if (verackReceived) {
|
} else if (verackReceived) {
|
||||||
self.emit("established");
|
self.emit("established");
|
||||||
|
@ -256,27 +256,21 @@ TcpTransport.prototype.listen = function() {
|
||||||
var server = self._server = net.createServer();
|
var server = self._server = net.createServer();
|
||||||
server.listen.apply(server, arguments);
|
server.listen.apply(server, arguments);
|
||||||
|
|
||||||
// TODO(Kagami): We may want to specify some limits for number of
|
var clientIdCounter = 0;
|
||||||
// connected users.
|
|
||||||
|
// TODO(Kagami): Limit number of connected clients (220/192 per
|
||||||
|
// PyBitmessage).
|
||||||
server.on("connection", function(client) {
|
server.on("connection", function(client) {
|
||||||
var addr = client.remoteAddress;
|
var id = client.id = clientIdCounter++;
|
||||||
var port = client.remotePort;
|
self._clients[id] = client;
|
||||||
if (self._clients[addr]) {
|
|
||||||
// NOTE(Kagami): Doesn't allow more than one connection per IP.
|
|
||||||
// This may obstruct people behind NAT but we copy PyBitmessage's
|
|
||||||
// behavior here.
|
|
||||||
client.end();
|
|
||||||
return self.emit("warning", new Error(
|
|
||||||
unmap(addr) + " was tried to create second connection"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
self._clients[addr] = client;
|
|
||||||
client.on("close", function() {
|
client.on("close", function() {
|
||||||
delete self._clients[addr];
|
delete self._clients[id];
|
||||||
});
|
});
|
||||||
var transport = new self.constructor(self);
|
var transport = new self.constructor(self);
|
||||||
var accepted = true;
|
var incoming = true;
|
||||||
transport._setupClient(client, accepted);
|
transport._setupClient(client, incoming);
|
||||||
|
var addr = client.remoteAddress;
|
||||||
|
var port = client.remotePort;
|
||||||
self.emit("connection", transport, unmap(addr), port);
|
self.emit("connection", transport, unmap(addr), port);
|
||||||
// Emit "open" manually because "connect" for this socket won't be
|
// Emit "open" manually because "connect" for this socket won't be
|
||||||
// fired.
|
// fired.
|
||||||
|
@ -304,8 +298,8 @@ TcpTransport.prototype.send = function() {
|
||||||
TcpTransport.prototype.broadcast = function() {
|
TcpTransport.prototype.broadcast = function() {
|
||||||
var data = getmsg(arguments);
|
var data = getmsg(arguments);
|
||||||
if (this._server) {
|
if (this._server) {
|
||||||
Object.keys(this._clients).forEach(function(ip) {
|
Object.keys(this._clients).forEach(function(id) {
|
||||||
this._clients[ip].write(data);
|
this._clients[id].write(data);
|
||||||
}, this);
|
}, this);
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Not listening");
|
throw new Error("Not listening");
|
||||||
|
@ -316,8 +310,8 @@ TcpTransport.prototype.close = function() {
|
||||||
if (this._client) {
|
if (this._client) {
|
||||||
this._client.end();
|
this._client.end();
|
||||||
} else if (this._server) {
|
} else if (this._server) {
|
||||||
Object.keys(this._clients).forEach(function(ip) {
|
Object.keys(this._clients).forEach(function(id) {
|
||||||
this._clients[ip].end();
|
this._clients[id].end();
|
||||||
}, this);
|
}, this);
|
||||||
this._server.close();
|
this._server.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ WsTransport.prototype._handleTimeout = function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
WsTransport.prototype._setupClient = function(client, accepted) {
|
WsTransport.prototype._setupClient = function(client, incoming) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self._client = client;
|
self._client = client;
|
||||||
var verackSent = false;
|
var verackSent = false;
|
||||||
|
@ -89,8 +89,8 @@ WsTransport.prototype._setupClient = function(client, accepted) {
|
||||||
|
|
||||||
client.on("open", function() {
|
client.on("open", function() {
|
||||||
// NOTE(Kagami): This handler shouldn't be called at all for
|
// NOTE(Kagami): This handler shouldn't be called at all for
|
||||||
// accepted sockets but let's be sure.
|
// incoming connections but let's be sure.
|
||||||
if (!accepted) {
|
if (!incoming) {
|
||||||
// NOTE(Kagami): We may set timeout only after connection was
|
// NOTE(Kagami): We may set timeout only after connection was
|
||||||
// opened because socket may not yet be available when
|
// opened because socket may not yet be available when
|
||||||
// `_setupClient` is called.
|
// `_setupClient` is called.
|
||||||
|
@ -130,7 +130,7 @@ WsTransport.prototype._setupClient = function(client, accepted) {
|
||||||
}
|
}
|
||||||
self.send("verack");
|
self.send("verack");
|
||||||
verackSent = true;
|
verackSent = true;
|
||||||
if (accepted) {
|
if (incoming) {
|
||||||
self._sendVersion();
|
self._sendVersion();
|
||||||
} else if (verackReceived) {
|
} else if (verackReceived) {
|
||||||
established = true;
|
established = true;
|
||||||
|
@ -185,33 +185,15 @@ WsTransport.prototype.listen = function(options, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var server = self._server = new WebSocketServer(options, callback);
|
var server = self._server = new WebSocketServer(options, callback);
|
||||||
|
|
||||||
// TODO(Kagami): We may want to specify some limits for number of
|
// TODO(Kagami): Limit number of connected clients (220/192 per
|
||||||
// connected users.
|
// PyBitmessage).
|
||||||
server.on("connection", function(client) {
|
server.on("connection", function(client) {
|
||||||
var addr = client._socket.remoteAddress;
|
|
||||||
var port = client._remotePort;
|
|
||||||
var i;
|
|
||||||
|
|
||||||
// NOTE(Kagami): O(n) search because `clients` array is already
|
|
||||||
// provided by `ws` library. We may want to optmize it though and
|
|
||||||
// also disable `clientTracking` option.
|
|
||||||
for (i = 0; i < server.clients.length; i++) {
|
|
||||||
if (server.clients[i] !== client &&
|
|
||||||
server.clients[i]._socket.remoteAddress === addr) {
|
|
||||||
// NOTE(Kagami): Doesn't allow more than one connection per IP.
|
|
||||||
// This may obstruct people behind NAT but we copy
|
|
||||||
// PyBitmessage's behavior here.
|
|
||||||
client.close();
|
|
||||||
return self.emit("warning", new Error(
|
|
||||||
unmap(addr) + " was tried to create second connection"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var transport = new self.constructor(self);
|
var transport = new self.constructor(self);
|
||||||
var accepted = true;
|
var incoming = true;
|
||||||
transport._setupClient(client, accepted);
|
transport._setupClient(client, incoming);
|
||||||
transport._handleTimeout();
|
transport._handleTimeout();
|
||||||
|
var addr = client._socket.remoteAddress;
|
||||||
|
var port = client._socket.remotePort;
|
||||||
self.emit("connection", transport, unmap(addr), port);
|
self.emit("connection", transport, unmap(addr), port);
|
||||||
// Emit "open" manually because it won't be fired for already opened
|
// Emit "open" manually because it won't be fired for already opened
|
||||||
// socket.
|
// socket.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user