Skip to content

Instantly share code, notes, and snippets.

@mhoyer
Created September 2, 2014 16:17
Show Gist options
  • Save mhoyer/9010254bf0c31f9eed1b to your computer and use it in GitHub Desktop.
Save mhoyer/9010254bf0c31f9eed1b to your computer and use it in GitHub Desktop.
Simple Node.js load balancer
var net = require('net');
var globalConnectionCount = 0;
module.exports = function(srcPort, dstMaps) {
var roundRobinIndex = 0;
var balancer = net.createServer(function (inboundSocket) {
var cnx = globalConnectionCount++ + ': ';
var connected = false;
var buffers = new Array();
// new proxy per connection
var dstMap = dstMaps[roundRobinIndex++];
var dst = dstMap['host'] + ':' + dstMap['port'];
roundRobinIndex = roundRobinIndex % dstMaps.length;
console.log(cnx + ' ---> [] ---> ' + dst + ' new');
// create and configure new outbound socket to connect to chosen destination
var outboundSocket = new net.Socket();
outboundSocket.connect(parseInt(dstMap['port']), dstMap['host'], function () {
connected = true;
if (buffers.length > 0) {
for (i = 0; i < buffers.length; i++) {
outboundSocket.write(buffers[i]);
}
}
}).on("error", function (e) {
console.log(cnx + ' ---> [] -X-> ' + dst + ' error: ' + e);
inboundSocket.end();
}).on('data', function (data) {
inboundSocket.write(data);
}).on("close", function(had_error) {
console.log(cnx + ' ---> [] |-> ' + dst + ' close (had_error:' + had_error + ')');
inboundSocket.end();
});
// configure inbound socket to connect to chosen destination
inboundSocket.on("error", function (e) {
console.log(cnx + ' -X-> [] ---> ' + dst + ' error: ' + e);
outboundSocket.end();
}).on("data", function (data) {
if (connected) {
outboundSocket.write(data);
} else {
buffers[buffers.length] = data;
}
}).on("close", function(had_error) {
console.log(cnx + ' -| [] ---> ' + dst + ' close (had_error:' + had_error + ')');
outboundSocket.end();
outboundSocket.destroy();
});
});
balancer.listen(srcPort);
console.log("Listening for TCP connections on:", srcPort);
};
@mhoyer
Copy link
Author

mhoyer commented Sep 2, 2014

Sample usage lb.js:

var lb = require('./loadbalancer.js')

var portMappings = {
  8080: [ {host:'localhost', port:80},
          {host:'shadow.local', port:80} ],
  8443: [ {host:'localhost', port:443},
          {host:'shadow.local', port:443} ]
};

for(var srcPort in portMappings) {
  lb(srcPort, portMappings[srcPort]);
}

Should be launched with:

$ node lb.js
Listening for TCP connections on 8080
Listening for TCP connections on 8443

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment