Я запускаю приложение node.js / express / socket.io в режиме кластера.
Я запускаю внешний сервер для мастер-процесса и внутренние серверы для рабочих, как показано в следующем коде.
if (cluster.isMaster) {
var workers = [];
var spawn = function(i) {
workers[i] = cluster.fork();
// Optional: Restart worker on exit
workers[i].on('exit', function(code, signal) {
console.log('Process exited! respawning worker no: ', i);
spawn(i);
});
};
// Spawn workers.
for (var i = 0; i < numCPUs; i++) {
spawn(i);
}
var worker_index = function(ip, len) {
return farmhash.fingerprint32(ip) % len; // Farmhash is the fastest and works with IPv6, too
};
// Create the outside facing server listening on our port.
var server = net.createServer({ pauseOnConnect: true }, function(connection) {
//!!!! the connection.remoteAddress causes issues with reverse proxy, however here not important as socket.io is used only for a global signalling to all clients
// console.log(connection.remoteAddress);
var worker = workers[worker_index(connection.remoteAddress, numCPUs)];
worker.send('sticky-session:connection', connection);
}).listen(port);
console.log('***************************************');
console.log('listening EXTERNALLY http://localhost:' + port);
console.log("This system has " + numCPUs + " virtual or real CPUs");
console.log('***************************************');
connection.remoteAddress // --> this is 127.0.0.1
} else {
// all worker processes enter the app from server.js
require("./server.js");
}
А затем в server.js, который запускается в соответствии с количеством ядер, доступных в системе.
const rateLimit = require('express-rate-limit');
...
app.enable("trust proxy"); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
...
app.use('/api/', apiLimiter); // --> this does not work as the real IP is not available
...
//startup the HTTP server
server.listen(0, 'localhost', function(err) {
console.log('***************************************');
console.log('***************************************');
console.log('listening INTERNALLY http://localhost:0');
console.log('***************************************');
});
В этом коде ограничение API (express-rate-limit) из node.js не работает. Я подозреваю, что это потому, что IP-адрес всегда одинаков на внутреннем сервере (127.0.0.1, localhost).
После создания http-сервера я могу получить реальный IP с помощью следующей команды:
req.headers['x-real-ip'] || req.connection.remoteAddress;
Но это не работает до создания http-сервера, но мне нужно это, чтобы включить ограничитель API.
Почему-то мне нужно передать IP-адрес с внешнего сервера, который, похоже, является TCP-сервером.
Есть ли способ получить реальный IP в самом начале до создания http-сервера?