Dapatkan alamat IP klien di socket.io

132

Saat menggunakan socket.IO di server Node.js, apakah ada cara mudah untuk mendapatkan alamat IP dari koneksi yang masuk? Saya tahu Anda bisa mendapatkannya dari koneksi HTTP standar, tetapi socket.io adalah sedikit binatang yang berbeda.

Toji
sumber
3
Sedikit bersinggungan, tetapi konsol.cat (soket) mungkin dapat membantu dengan secara rekursif membuang segala sesuatu di objek soket ke konsol
izb
4
@izb Poin bagus, tapi console.dir(socket)mungkin itu yang Anda maksud
LanguagesNamedAfterCofee

Jawaban:

160

Oke, mulai 0.7.7 ini tersedia, tetapi tidak dengan cara yang dijelaskan lubar. Saya akhirnya perlu mem-parsing melalui beberapa log komit di git hub untuk mencari tahu ini, tetapi kode berikut ini benar-benar bekerja untuk saya sekarang:

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
sumber
5
Um ... karena dia .connection.remoteAddress dan milikku .handshake.address?
Toji
2
@ GarciadelCastillo Anda mungkin berada di belakang proxy. coba ini: stackoverflow.com/a/11187053/971459
Samson
4
Tidak berfungsi di v1.0 - hanya mencatat alamat host untuk saya.
Iest
1
Pada versi 1.3.7, ini kembali::ffff:127.0.0.1
dmr07
3
socket.request.connection.remoteAddressuntuk versi 1.x
Lukas Liesis
72

untuk 1.0.4:

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

  console.log(clientIp);
});
pipih
sumber
Di mana Anda mendapatkan info? Saya pikir saya telah membaca semua dokumen untuk socket.io dan tidak melihat ini. Ini bekerja dengan sempurna untuk menyelesaikan masalah saya mirip dengan OP.
MikeB
1
Soket console.log hanya untuk melihat semua informasi yang tersedia, saya percaya itu terus berubah karena tidak didokumentasikan.
Pez Cuckow
6
Di v1.2.1, socket.request.connection.remoteAddressdan socket.request.connection.remotePortbekerja untuk saya. Namun, saya tidak melihat salah satu dari properti ini terdaftar ketika saya mencoba: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); Mengapa tidak?
Jeffrey LeCours
1
Bekerja di 1.3.4 juga. Terima kasih
lima_fil
3
Pada versi 1.3.7, ini kembali::ffff:127.0.0.1
dmr07
46

Jika Anda menggunakan server lain sebagai proxy terbalik, semua bidang yang disebutkan akan berisi localhost. Solusi termudah adalah menambahkan header untuk ip / port di server proxy.

Contoh untuk nginx: tambahkan ini setelah Anda proxy_pass:

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

Ini akan membuat header tersedia di server node socket.io:

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

Perhatikan bahwa tajuk dikonversi secara internal ke huruf kecil.

Jika Anda menghubungkan server simpul langsung ke klien,

var ip = socket.conn.remoteAddress;

bekerja dengan socket.io versi 1.4.6 untuk saya.

zuim
sumber
5
Ini adalah solusi terbaik, jawaban lain tidak berfungsi jika nodejs ada di belakang proxy
Alfredo Gt
2
@zuim, Tuan, adalah pahlawan saya!
Flavio
20

Untuk penggunaan versi socket.io terbaru

socket.request.connection.remoteAddress

Sebagai contoh:

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

berhati-hatilah bahwa kode di bawah ini mengembalikan IP Server, bukan IP Klien

var address = socket.handshake.address;
console.log('New connection from ' + address.address + ':' + address.port);
SlyBeaver
sumber
2
saya akan mencoba kode jabat tangan itu, terima kasih telah menunjukkan itu tidak berguna !!
RozzA
1
Versi apa yang dimaksud dengan "versi socket.io terbaru"? Harap berikan versi spesifik.
Akseli Palén
Terbaru untuk Juli 2014
SlyBeaver
8

Menggunakan 1.0.6versi terbaru dari Socket.IOdan memiliki aplikasi saya digunakan Heroku, saya mendapatkan klien IPdan portmenggunakan headerske 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']);

}
Balthazar
sumber
6

Sejak socket.io 1.1.0, saya menggunakan:

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

Sunting : Perhatikan bahwa ini bukan bagian dari API resmi, dan karena itu tidak dijamin untuk bekerja di rilis socket.io mendatang.

Lihat juga tautan yang relevan ini: masalah engine.io

nha
sumber
1
Dikonfirmasi dengan 1.3.3 juga.
Codesleuth
@Rachael @ Codesleuth Terima kasih atas konfirmasi untuk versi-versinya, sangat kami hargai. Saya mendapatkan beberapa upvotes jadi saya kira ini masih valid, tetapi saya belum menguji diri saya.
nha
6

Versi 0.7.7 dari Socket.IO sekarang mengklaim untuk mengembalikan alamat IP klien. Saya sudah sukses dengan:

var socket = io.listen(server);
socket.on('connection', function (client) {
  var ip_address = client.connection.remoteAddress;
}
lubar
sumber
2
client.conn.remoteAddress; dalam versi yang lebih baru.
Mujtaba Kably
4

Ini sepertinya berhasil:

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
sumber
1
Ini selalu kembali 127.0.0.1untuk saya, bukan IP klien (node.js berjalan di server jauh).
Daniel W.
coba socket.request.connection.remoteAddress
Lukas Liesis
Berikan versi Socket.io yang Anda gunakan.
Akseli Palén
4

Saya telah menemukan bahwa dalam socket.handshake.headers ada sebuah diteruskan untuk alamat yang tidak muncul pada mesin lokal saya. Dan saya bisa mendapatkan alamat jarak jauh menggunakan:

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

Ini di sisi server dan bukan sisi klien.

Ufb007
sumber
1
Semua yang saya coba kembali ::ffff:127.0.0.1tetapi ini memberi saya IP yang sebenarnya
Steven Pothoven
love u, semua jawaban lain beri saya loopback ip, hanya header ini yang berfungsi!
datdinhquoc
Ini adalah solusi untuk versi terbaru [2.2.0]. Segala sesuatu yang dikembalikan server ip untuk saya.
Abdul Sadik Yalcin
3

Dari membaca kode sumber socket.io sepertinya metode "mendengarkan" mengambil argumen (server, opsi, fn) dan jika "server" adalah turunan dari server HTTP / S, ia hanya akan membungkusnya untuk Anda.

Jadi Anda mungkin bisa memberikannya server kosong yang mendengarkan acara 'koneksi' dan menangani soket RemoteAddress; Namun, hal-hal mungkin sangat sulit jika Anda harus mengaitkan alamat itu dengan objek socket.io Socket yang sebenarnya.

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

Mungkin lebih mudah untuk mengirimkan tambalan ke socket.io di mana objek Socket mereka sendiri diperpanjang dengan properti RemoteAddress yang ditugaskan pada waktu koneksi ...

maerics
sumber
Patch ini kemungkinan besar akan dimasukkan dalam rilis selanjutnya github.com/LearnBoost/Socket.IO-node/pull/286
mak
3

Sangat mudah. Put pertama

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

console.log(socket);

Anda akan melihat semua bidang soket. kemudian gunakan CTRL + F dan cari alamat kata. Akhirnya, ketika Anda menemukan bidang remoteAddress menggunakan titik-titik untuk memfilter data. dalam kasus saya itu

console.log(socket.conn.remoteAddress);
geniant
sumber
Hari ini saya menemukan solusi yang sama dalam masalah yang sama!
Filippo1980
Ini tidak memberikan IP titik akhir klien. Dalam kasus saya itu hanya mengembalikan IP dari server proxy terbalik.
Akseli Palén
3

Di socket.io 2.0 : Anda dapat menggunakan:

socket.conn.transport.socket._socket.remoteAddress

bekerja dengan transports: ['websocket']

Chris
sumber
3

Ini berfungsi untuk versi 2.3.0 terbaru :

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

pada socket.io1.3.4 Anda memiliki kemungkinan berikut.

socket.handshake.address,

socket.conn.remoteAddress atau

socket.request.client._peername.address

Yaki Klein
sumber
2

Dalam versi v2.3.0

ini bekerja untuk saya:

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

menggunakan socket.request.connection.remoteAddress

DuckHunter
sumber
4
Pada versi 1.3.7, ini kembali::ffff:127.0.0.1
dmr07
1

Versi terbaru berfungsi dengan:

console.log(socket.handshake.address);
Khanasyubighi
sumber
5
Pada versi 1.3.7, ini kembali::ffff:127.0.0.1
dmr07
serupa 1.4.8 :: ffff: 10.0.0.7
Xin
1
@ dmr07 ini adalah versi IPv6. Anda dapat memaksa IPv4 dengan membuat server http mendengarkan 0.0.0.0. Terkait: stackoverflow.com/a/37378670/5138796
darrachequesne
Anda dapat melakukan console.log (socket.handshake.address.substring (7)) hanya akan mencetak ip 127.0.0.1
node_man
1

Selamat datang di 2019, di mana naskah perlahan mulai menguasai dunia. Jawaban lain masih sangat valid. Namun, saya hanya ingin menunjukkan kepada Anda bagaimana Anda dapat mengatur ini di lingkungan yang diketik.

Jika Anda belum. Pertama Anda harus menginstal beberapa dependensi (yaitu dari commandline: 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"
  }

Saya mendefinisikan impor menggunakan impor ES6 (yang harus Anda aktifkan dalam tsconfig.jsonfile Anda terlebih dahulu.)

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

Karena saya menggunakan naskah saya sudah mengetik penuh sekarang, pada semua yang saya lakukan dengan objek-objek ini.

Jadi, jelas, pertama Anda memerlukan server http:

const handler = express();

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

Saya kira Anda sudah melakukan semua itu. Dan Anda mungkin sudah menambahkan socket io ke dalamnya:

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

Selanjutnya, untuk penanganan koneksi socket-io baru, Anda dapat meletakkan SocketIO.Sockettipe pada parameternya.

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

Dan akhirnya, karena kita memiliki pengetikan penuh sekarang, kita dapat dengan mudah mengambil ip dari soket kita, tanpa menebak:

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

Dalam 1.3.5:

var clientIP = socket.handshake.headers.host;
Syscall
sumber
5
Pada versi 1.3.7, ini mengembalikan url halaman, bukan ip
dmr07