Отримайте IP-адресу клієнта в socket.io


132

Якщо ви використовуєте socket.IO на сервері Node.js, чи є простий спосіб отримати IP-адресу вхідного з'єднання? Я знаю, що ви можете отримати це зі стандартного HTTP-з'єднання, але socket.io трохи інший звір.


3
Незначна дотична, але console.cat (socket), можливо, допомогла б рекурсивним скиданням всього в об'єкт socket на консоль
izb

4
@izb Добрий момент, але console.dir(socket)може бути, що ви мали на увазі
LanguagesNamedAfterCofee

Відповіді:


160

Гаразд, на 0.7.7 це доступно, але не так, як описує Любар. Мені потрібно було проаналізувати деякі журнали фіксації на git hub, щоб визначити це, але наступний код насправді працює для мене:

var io = require('socket.io').listen(server);

io.sockets.on('connection', function (socket) {
  var address = socket.handshake.address;
  console.log('New connection from ' + address.address + ':' + address.port);
});

5
Гм ... тому що його є .connection.remoteAddress, а моє - .handshake.address?
Тоджі

2
@GarciadelCastillo, ймовірно, ви за проксі-сервером. спробуйте це: stackoverflow.com/a/11187053/971459
Самсон

4
Не працює в v1.0 - він просто записує адресу хоста для мене.
Iest,

1
Щодо версії 1.3.7, це повертається::ffff:127.0.0.1
dmr07

3
socket.request.connection.remoteAddressдля версії 1.x
Лукас Ліесіс

72

за 1.0.4:

io.sockets.on('connection', function (socket) {
  var socketId = socket.id;
  var clientIp = socket.request.connection.remoteAddress;

  console.log(clientIp);
});

Звідки ви взяли інформацію? Я думав, що прочитав усі документи для socket.io і цього не бачив. Це прекрасно працювало для вирішення моїх проблем, подібних до ОП.
MikeB

1
Просто console.log socket, щоб переглянути всю наявну інформацію, я вважаю, що вона постійно змінюється, оскільки вона не документально підтверджена.
Pez Cuckow

6
У версії 1.2 socket.request.connection.remoteAddressі socket.request.connection.remotePortпрацюйте для мене. Однак я не бачив жодної з цих властивостей, перелічених під час спроби: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); чому б ні?
Jeffrey LeCours

1
Працює і в 1.3.4. Дякую
lima_fil

3
Щодо версії 1.3.7, це повертається::ffff:127.0.0.1
dmr07

46

Якщо ви використовуєте інший сервер як зворотний проксі, всі згадані поля будуть містити localhost. Найпростіший спосіб вирішити - додати заголовки для ip / port на проксі-сервері.

Приклад для nginx: додайте це після свого proxy_pass:

proxy_set_header  X-Real-IP $remote_addr;
proxy_set_header  X-Real-Port $remote_port;

Це зробить заголовки доступними на сервері вузла socket.io:

var ip = socket.handshake.headers["x-real-ip"];
var port = socket.handshake.headers["x-real-port"];

Зауважте, що заголовок внутрішньо перетворений на малі регістри.

Якщо ви підключаєте сервер вузлів безпосередньо до клієнта,

var ip = socket.conn.remoteAddress;

для мене працює socket.io версія 1.4.6.


5
Це найкраще рішення, інші відповіді не спрацьовують, якщо nodejs стоїть за проксі-сервером
Alfredo Gt

2
@zuim Ви, сер, мій герой!
Флавіо

20

Для використання останньої версії socket.io

socket.request.connection.remoteAddress

Наприклад:

var socket = io.listen(server);
socket.on('connection', function (client) {
  var client_ip_address = socket.request.connection.remoteAddress;
}

майте на увазі, що наведений нижче код повертає IP-адресу Сервера, а не IP-адресу клієнта

var address = socket.handshake.address;
console.log('New connection from ' + address.address + ':' + address.port);

2
Я збирався спробувати цей код рукостискання, дякую, що вказав, що це марно !!
RozzA

1
Яка версія означає "найсвіжіша версія socket.io"? Укажіть конкретну версію.
Акселі Пален

Останнє для липня 2014 року
SlyBeaver

8

Використовуючи останню 1.0.6версію Socket.IOі мати моє додаток розгортається на Heroku, я отримую клієнт IPі portвикористовуючи headersв socket handshake:

var socketio = require('socket.io').listen(server);

socketio.on('connection', function(socket) {

  var sHeaders = socket.handshake.headers;
  console.info('[%s:%s] CONNECT', sHeaders['x-forwarded-for'], sHeaders['x-forwarded-port']);

}

6

Оскільки socket.io 1.1.0, я використовую:

io.on('connection', function (socket) {
  console.log('connection :', socket.request.connection._peername);
  // connection : { address: '192.168.1.86', family: 'IPv4', port: 52837 }
}

Редагувати : Зауважте, що це не є частиною офіційного API, а тому не гарантовано працювати в майбутніх випусках socket.io.

Також дивіться це відповідне посилання: випуск engine.io


1
Також підтверджено з 1.3.3.
Codesleuth

@Rachael @ Codesleuth Дякую за підтвердження версій, це дуже цінується. Я отримую кілька оновлень, тому я гадаю, що це все-таки справедливо, але я ще не перевіряв себе.
Nha

6

Версія 0.7.7 Socket.IO тепер вимагає повернути IP-адресу клієнта. Я мав успіх у:

var socket = io.listen(server);
socket.on('connection', function (client) {
  var ip_address = client.connection.remoteAddress;
}

2
його client.conn.remoteAddress; у новіших версіях.
Муджтаба Каблі

4

Це, здається, працює:

var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
  var endpoint = socket.manager.handshaken[socket.id].address;
  console.log('Client connected from: ' + endpoint.address + ":" + endpoint.port);
});

1
Це завжди повертається 127.0.0.1для мене, а не IP-адреси клієнта (node.js працює на віддаленому сервері).
Даніель В.

спробуйте socket.request.connection.remoteAddress
Лукас Лейсіс

Надайте версію Socket.io, яку ви використовували.
Акселі Пален

4

Я виявив, що в межах socket.handshake.headers є переадресована адреса, яка не відображається на моїй локальній машині. І мені вдалося отримати віддалену адресу за допомогою:

socket.handshake.headers['x-forwarded-for']

Це на стороні сервера, а не на стороні клієнта.


1
Все інше, що я спробував, повернувся, ::ffff:127.0.0.1але це дало мені фактичну IP
Стівен Потховен

love u, всі інші анвери дають мені петлю ip, тільки цей заголовок працює!
datdinhquoc

Це рішення для останньої версії [2.2.0]. Все інше повернув ip сервера для мене.
Абдул Садік Ялчин

3

Зчитування вихідного коду socket.io виглядає так, що метод "прослуховування" бере аргументи (сервер, параметри, fn), і якщо "сервер" є екземпляром сервера HTTP / S, він просто оберне його.

Таким чином, ви можете, мабуть, дати йому порожній сервер, який прослуховує подію "з'єднання" та обробляє socket remoteAddress; однак, справи можуть бути дуже складними, якщо вам потрібно пов’язати цю адресу з фактичним об'єктом socket.io Socket.

var http = require('http')
  , io = require('socket.io');
io.listen(new http.Server().on('connection', function(sock) {
  console.log('Client connected from: ' + sock.remoteAddress);
}).listen(80));

Можливо, буде простіше подати виправлення в socket.io, де власний об'єкт Socket розширюється властивістю remoteAddress, призначеною під час з'єднання ...


Цей патч, швидше за все, буде включено до наступного випуску github.com/LearnBoost/Socket.IO-node/pull/286
мак

3

Дуже легко. Спочатку поклав

io.sockets.on('connection', function (socket) {

console.log(socket);

Ви побачите всі поля сокета. потім використовуйте CTRL + F і шукайте адресу слова. Нарешті, коли ви знайдете поле remoteAddress, використовуйте крапки для фільтрації даних. в моєму випадку це так

console.log(socket.conn.remoteAddress);

Сьогодні я знайшов те саме рішення у подібній справі!
Filippo1980

Це не дає IP-адреси клієнта кінцевої точки. У моєму випадку він просто повертає IP зворотного проксі-сервера.
Акселі Пален

3

У socket.io 2.0 : ви можете використовувати:

socket.conn.transport.socket._socket.remoteAddress

працює з transports: ['websocket']


3

Це працює для останньої версії 2.3.0 :

io.on('connection', socket => {
   const ip = socket.handshake.headers[x-forwarded-for] || socket.conn.remoteAddress.split(":")[3];
   console.log(ip);
});

2

на socket.io1.3.4 у вас є такі можливості.

socket.handshake.address,

socket.conn.remoteAddress або

socket.request.client._peername.address



1

використання socket.request.connection.remoteAddress


4
Щодо версії 1.3.7, це повертається::ffff:127.0.0.1
dmr07

1

Остання версія працює з:

console.log(socket.handshake.address);

5
Станом на версію 1.3.7 , це повертається::ffff:127.0.0.1
dmr07

подібний 1.4.8 :: ffff: 10.0.0.7
Xin

1
@ dmr07 це версія IPv6. Ви можете змусити IPv4, змусивши прослухати http-сервер 0.0.0.0. Пов’язано: stackoverflow.com/a/37378670/5138796
darrachequesne

ви можете зробити console.log (socket.handshake.address.substring (7)), він просто надрукує ip 127.0.0.1
node_man

1

Ласкаво просимо у 2019 році, коли машинопис повільно переймає світ. Інші відповіді все ще цілком справедливі. Однак я просто хотів показати вам, як ви можете налаштувати це в набраному середовищі.

Якщо ви ще цього не зробили. Ви повинні спочатку встановити деяку залежність (наприклад , з командного рядка: npm install <dependency-goes-here> --save-dev)

  "devDependencies": {
    ...
    "@types/express": "^4.17.2",
    ...
    "@types/socket.io": "^2.1.4",
    "@types/socket.io-client": "^1.4.32",
    ...
    "ts-node": "^8.4.1",
    "typescript": "^3.6.4"
  }

Я визначив імпорт, використовуючи імпорт ES6 (який слід включити tsconfig.jsonспочатку у своєму файлі).

import * as SocketIO from "socket.io";
import * as http from "http";
import * as https from "https";
import * as express from "express";

Оскільки я використовую машинопис, я зараз повністю набираю текст у всьому, що я роблю з цими об'єктами.

Отже, очевидно, спочатку вам потрібен http-сервер:

const handler = express();

const httpServer = (useHttps) ?
  https.createServer(serverOptions, handler) :
  http.createServer(handler);

Я думаю, ви вже все це зробили. І ви, мабуть, вже додали в нього socket io:

const io = SocketIO(httpServer);
httpServer.listen(port, () => console.log("listening") );
io.on('connection', (socket) => onSocketIoConnection(socket));

Далі, для обробки нових з'єднань socket-io, ви можете встановити SocketIO.Socketтип на його параметр.

function onSocketIoConnection(socket: SocketIO.Socket) {      
  // I usually create a custom kind of session object here.
  // then I pass this session object to the onMessage and onDisconnect methods.

  socket.on('message', (msg) => onMessage(...));
  socket.once('disconnect', (reason) => onDisconnect(...));
}

І, нарешті, оскільки ми вже повністю набрали текст, ми можемо легко отримати ip з нашого сокета, не здогадуючись:

const ip = socket.conn.remoteAddress;
console.log(`client ip: ${ip}`);

-1

У 1.3.5:

var clientIP = socket.handshake.headers.host;

5
З версії 1.3.7, це повертає URL-адресу сторінки, а не ip
dmr07
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.