Obtenga la dirección IP del cliente en socket.io

132

Al usar socket.IO en un servidor Node.js, ¿hay alguna manera fácil de obtener la dirección IP de una conexión entrante? Sé que puedes obtenerlo de una conexión HTTP estándar, pero socket.io es una bestia un poco diferente.

Toji
fuente
3
Tangente ligero, pero console.cat (socket) posiblemente podrían haber ayudado por el vertido de forma recursiva todo en el objeto conector en la consola
izb
44
@izb Buen punto, pero console.dir(socket)podría ser lo que querías decir
LanguagesNamedAfterCofee

Respuestas:

160

Bien, a partir de 0.7.7 esto está disponible, pero no de la manera que describe lubar. Terminé necesitando analizar algunos registros de confirmación en git hub para resolver esto, pero el siguiente código realmente funciona para mí ahora:

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);
});
Toji
fuente
55
Um ... porque el suyo es .connection.remoteAddress y el mío es .handshake.address?
Toji
2
@GarciadelCastillo probablemente estés detrás de un proxy. intente esto: stackoverflow.com/a/11187053/971459
Samson
44
No funciona en v1.0, solo registra la dirección del host para mí.
Iest
1
A partir de la versión 1.3.7, esto vuelve::ffff:127.0.0.1
dmr07
3
socket.request.connection.remoteAddresspara la versión 1.x
Lukas Liesis
72

para 1.0.4:

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

  console.log(clientIp);
});
aplastar
fuente
¿De dónde sacaste la información? Pensé que había leído todos los documentos para socket.io y no vi esto. Funcionó perfectamente para resolver mis problemas de manera similar al OP.
MikeB
1
Solo consola.log socket para ver toda la información disponible, creo que sigue cambiando porque no está documentado.
Pez Cuckow
66
En v1.2.1, socket.request.connection.remoteAddressy socket.request.connection.remotePorttrabaja para mí. Sin embargo, no vi ninguna de estas propiedades enumeradas cuando intenté: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); ¿Por qué no?
Jeffrey LeCours
1
Funciona en 1.3.4 también. Gracias
lima_fil
3
A partir de la versión 1.3.7, esto vuelve::ffff:127.0.0.1
dmr07
46

Si utiliza otro servidor como proxy inverso, todos los campos mencionados contendrán localhost. La solución más fácil es agregar encabezados para ip / port en el servidor proxy.

Ejemplo para nginx: agregue esto después de su proxy_pass:

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

Esto hará que los encabezados estén disponibles en el servidor de nodo socket.io:

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

Tenga en cuenta que el encabezado se convierte internamente a minúsculas.

Si está conectando el servidor de nodo directamente al cliente,

var ip = socket.conn.remoteAddress;

funciona con socket.io versión 1.4.6 para mí.

zuim
fuente
55
Esta es la mejor solución, las otras respuestas no funcionan si nodejs está detrás de un proxy
Alfredo Gt
2
@zuim Señor, eres mi héroe!
Flavio
20

Para la última versión de socket.io use

socket.request.connection.remoteAddress

Por ejemplo:

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

tenga en cuenta que el siguiente código devuelve la IP del servidor, no la IP del cliente

var address = socket.handshake.address;
console.log('New connection from ' + address.address + ':' + address.port);
SlyBeaver
fuente
2
Estaba a punto de probar ese código de apretón de manos, ¡gracias por señalar que es inútil!
RozzA
1
¿Qué versión se entiende por "última versión de socket.io"? Proporcione una versión específica.
Akseli Palén
Lo último para julio de 2014
SlyBeaver,
8

Utilizando la última 1.0.6versión de Socket.IOmi aplicación y la tengo implementada Heroku, obtengo el cliente IPy lo portuso headersen 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']);

}
Baltasar
fuente
6

Desde socket.io 1.1.0, uso:

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

Editar : tenga en cuenta que esto no es parte de la API oficial y, por lo tanto, no se garantiza que funcione en futuras versiones de socket.io.

Consulte también este enlace relevante: problema engine.io

nha
fuente
1
Confirmado con 1.3.3 también.
Codesleuth
@ Rachael @ Codesleuth Gracias por la confirmación de las versiones, es muy apreciada. Estoy recibiendo algunos votos positivos, así que supongo que esto todavía es válido, pero no me he probado.
nha
6

La versión 0.7.7 de Socket.IO ahora afirma devolver la dirección IP del cliente. He tenido éxito con:

var socket = io.listen(server);
socket.on('connection', function (client) {
  var ip_address = client.connection.remoteAddress;
}
lubar
fuente
2
su client.conn.remoteAddress; en las versiones más nuevas
Mujtaba Kably
4

Esto parece funcionar:

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);
});
Robert Larsen
fuente
1
Esto siempre 127.0.0.1me devuelve , no la IP del cliente (node.js se ejecuta en el servidor remoto).
Daniel W.
intente socket.request.connection.remoteAddress
Lukas Liesis
Proporcione la versión de Socket.io que estaba utilizando.
Akseli Palén
4

He descubierto que dentro de socket.handshake.headers hay una dirección de reenvío que no aparece en mi máquina local. Y pude obtener la dirección remota usando:

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

Esto está en el lado del servidor y no del lado del cliente.

Ufb007
fuente
1
Todo lo demás que probé regresó ::ffff:127.0.0.1pero esto me dio la IP real
Steven Pothoven
te amo, todas las otras respuestas me dan ip de bucle invertido, ¡solo este encabezado funciona!
datdinhquoc
Esta es la solución para la última versión [2.2.0]. Todo lo demás me devolvió el servidor ip.
Abdul Sadik Yalcin
3

Al leer el código fuente de socket.io parece que el método "escuchar" toma argumentos (servidor, opciones, fn) y si "servidor" es una instancia de un servidor HTTP / S, simplemente lo envolverá por usted.

Por lo tanto, presumiblemente podría darle un servidor vacío que escucha el evento de 'conexión' y maneja el socket remoteAddress; sin embargo, las cosas pueden ser muy difíciles si necesita asociar esa dirección con un objeto socket.io real.

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));

Podría ser más fácil enviar un parche a socket.io en el que su propio objeto Socket se extiende con la propiedad remoteAddress asignada en el momento de la conexión ...

maerics
fuente
Este parche probablemente se incluirá en la próxima versión github.com/LearnBoost/Socket.IO-node/pull/286
mak
3

Muy fácil. Primer puesto

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

console.log(socket);

Verá todos los campos de socket. luego use CTRL + F y busque la palabra dirección. Finalmente, cuando encuentre el campo remoteAddress use puntos para filtrar datos. en mi caso es

console.log(socket.conn.remoteAddress);
genio
fuente
¡Hoy encontré la misma solución en un asunto similar!
Filippo1980
Esto no proporciona la IP del punto final del cliente. En mi caso, solo devuelve la IP del servidor proxy inverso.
Akseli Palén
3

En socket.io 2.0 : puede usar:

socket.conn.transport.socket._socket.remoteAddress

funciona con transports: ['websocket']

Chris '
fuente
3

Esto funciona para la última versión 2.3.0 :

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

en socket.io1.3.4 tiene las siguientes posibilidades.

socket.handshake.address,

socket.conn.remoteAddress o

socket.request.client._peername.address

Yaki Klein
fuente
2

En la versión v2.3.0

este trabajo para mi:

socket.handshake.headers['x-forwarded-for'].split(',')[0]
Intercooler Rizuwan
fuente
1

utilizar socket.request.connection.remoteAddress

DuckHunter
fuente
44
A partir de la versión 1.3.7, esto regresa::ffff:127.0.0.1
dmr07
1

La última versión funciona con:

console.log(socket.handshake.address);
Khanasyubighi
fuente
55
A partir de la versión 1.3.7, esto regresa::ffff:127.0.0.1
dmr07
similar 1.4.8 :: ffff: 10.0.0.7
Xin
1
@ dmr07 esta es la versión IPv6. Puede forzar el IPv4 haciendo que el servidor http escuche 0.0.0.0. Relacionado: stackoverflow.com/a/37378670/5138796
darrachequesne
puede hacer console.log (socket.handshake.address.substring (7)) simplemente imprimirá la ip 127.0.0.1
node_man
1

Bienvenido en 2019, donde el mecanografiado se apodera lentamente del mundo. Otras respuestas siguen siendo perfectamente válidas. Sin embargo, solo quería mostrarle cómo puede configurar esto en un entorno mecanografiado.

En caso de que aún no lo hayas hecho. Primero debe instalar algunas dependencias (es decir, desde la línea de comandos: 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"
  }

Definí las importaciones utilizando las importaciones de ES6 (que tsconfig.jsonprimero debe habilitar en su archivo).

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

Como uso el mecanografiado, ahora tengo una escritura completa, en todo lo que hago con estos objetos.

Entonces, obviamente, primero necesitas un servidor http:

const handler = express();

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

Supongo que ya hiciste todo eso. Y probablemente ya le haya agregado socket io:

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

Luego, para el manejo de nuevas conexiones socket-io, puede poner el SocketIO.Sockettipo en su parámetro.

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(...));
}

Y finalmente, porque ahora tenemos una escritura completa, podemos recuperar fácilmente la ip de nuestro socket, sin adivinar:

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

En 1.3.5:

var clientIP = socket.handshake.headers.host;
Syscall
fuente
55
A partir de la versión 1.3.7, esto devuelve la URL de la página, no ip
dmr07