Nhận địa chỉ IP của khách hàng trong socket.io


132

Khi sử dụng socket.IO trong máy chủ Node.js, có cách nào dễ dàng để lấy địa chỉ IP của kết nối đến không? Tôi biết bạn có thể lấy nó từ một kết nối HTTP tiêu chuẩn, nhưng socket.io là một con thú khác.


3
Tiếp tuyến nhẹ, nhưng console.cat (ổ cắm) có thể có thể giúp đỡ bằng cách đệ quy mọi thứ trong đối tượng ổ cắm vào bàn điều khiển
izb

4
@izb Điểm tốt, nhưng console.dir(socket)có thể là ý của bạn
Languages

Câu trả lời:


160

Được rồi, kể từ ngày 0.7.7, điều này có sẵn, nhưng không phải theo cách mà Lubar mô tả. Cuối cùng tôi cần phân tích cú pháp thông qua một số nhật ký cam kết trên git hub để tìm ra cái này, nhưng đoạn mã sau đây thực sự hoạt động với tôi bây giờ:

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
Ừm ... bởi vì anh ấy là .connection.remoteAddress và của tôi là .handshake.address?
Toji

2
@GarciadelCastillo bạn có thể đứng sau một proxy. hãy thử điều này: stackoverflow.com/a/11187053/971459
Samson

4
Không hoạt động trong v1.0 - nó chỉ ghi lại địa chỉ của máy chủ lưu trữ cho tôi.
Iest

1
Kể từ phiên bản 1.3.7, điều này trở lại::ffff:127.0.0.1
dmr07

3
socket.request.connection.remoteAddresscho phiên bản 1.x
Lukas Liesis

70

cho 1.0.4:

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

  console.log(clientIp);
});

Bạn đã lấy thông tin ở đâu? Tôi nghĩ rằng tôi đã đọc tất cả các tài liệu cho socket.io và không thấy điều này. Nó hoạt động hoàn hảo để giải quyết các vấn đề của tôi tương tự như OP.
MikeB

1
Chỉ cần ổ cắm console.log để xem tất cả các thông tin có sẵn, tôi tin rằng nó tiếp tục thay đổi vì nó không được ghi lại.
Pez Cuckow

6
Trong v1.2.1, socket.request.connection.remoteAddresssocket.request.connection.remotePortlàm việc cho tôi. Tuy nhiên, tôi đã không thấy một trong hai thuộc tính này được liệt kê khi tôi thử: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); Tại sao không?
Jeffrey LeCours

1
Hoạt động trong 1.3.4 cũng có. Cảm ơn
lima_fil 15/2/2015

3
Kể từ phiên bản 1.3.7, điều này trở lại::ffff:127.0.0.1
dmr07

46

Nếu bạn sử dụng một máy chủ khác làm proxy ngược, tất cả các trường được đề cập sẽ chứa localhost. Cách giải quyết đơn giản nhất là thêm các tiêu đề cho ip / port trong máy chủ proxy.

Ví dụ cho nginx: thêm cái này sau proxy_pass:

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

Điều này sẽ làm cho các tiêu đề có sẵn trong máy chủ nút socket.io:

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

Lưu ý rằng tiêu đề được chuyển đổi nội bộ sang chữ thường.

Nếu bạn đang kết nối máy chủ nút trực tiếp với máy khách,

var ip = socket.conn.remoteAddress;

hoạt động với socket.io phiên bản 1.4.6 cho tôi.


5
Đây là giải pháp tốt nhất, các câu trả lời khác không hoạt động nếu nodejs đứng sau proxy
Alfredo Gt

2
@zuim Bạn ơi, là anh hùng của tôi!
Flavio

20

Đối với phiên bản socket.io mới nhất, hãy sử dụng

socket.request.connection.remoteAddress

Ví dụ:

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

lưu ý rằng mã bên dưới trả về IP của máy chủ, không phải IP của máy khách

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

2
tôi đã định thử mã bắt tay đó, cảm ơn vì đã chỉ ra nó vô dụng !!
RozzA

1
Phiên bản nào có nghĩa là "phiên bản socket.io mới nhất"? Vui lòng cung cấp phiên bản cụ thể.
Akseli Palén

Mới nhất cho tháng 7 năm 2014
SlyBeaver

8

Sử dụng 1.0.6phiên bản mới nhất Socket.IOvà ứng dụng của tôi được triển khai Heroku, tôi nhận ứng dụng khách IPportsử dụng headersvào 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

Kể từ socket.io 1.1.0, tôi sử dụng:

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

Chỉnh sửa : Lưu ý rằng đây không phải là một phần của API chính thức và do đó không được đảm bảo để hoạt động trong các bản phát hành trong tương lai của socket.io.

Cũng xem liên kết có liên quan này: vấn đề engine.io


1
Khẳng định với 1.3.3 cũng được.
Codeleuth 7/2/2015

@Rachael @ Codeleuth Cảm ơn bạn đã xác nhận cho các phiên bản, nó được đánh giá cao. Tôi đang nhận được một vài upvote vì vậy tôi đoán điều này vẫn còn hiệu lực, nhưng tôi đã không tự kiểm tra.
nha

6

Phiên bản 0.7.7 của Socket.IO hiện yêu cầu trả lại địa chỉ IP của khách hàng. Tôi đã thành công với:

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

2
client của nó.conn.remoteAddress; trong các phiên bản mới hơn.
Mujtaba Kable

4

Điều này dường như làm việc:

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
Điều này luôn trả về 127.0.0.1cho tôi, không phải IP của máy khách (node.js chạy trên máy chủ từ xa).
Daniel W.

thử socket.request.connection.remoteAddress
Lukas Liesis

Vui lòng cung cấp phiên bản Socket.io bạn đang sử dụng.
Akseli Palén

4

Tôi đã tìm thấy rằng trong socket.handshake.headers có một địa chỉ được chuyển tiếp không xuất hiện trên máy cục bộ của tôi. Và tôi đã có thể lấy địa chỉ từ xa bằng cách sử dụng:

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

Đây là ở phía máy chủ và không phải phía khách hàng.


1
Mọi thứ khác tôi đã thử trả lại ::ffff:127.0.0.1nhưng điều này đã cho tôi IP thực tế
Steven Pothoven

yêu bạn, tất cả các anwers khác cho tôi loopback ip, chỉ tiêu đề này hoạt động!
datdinhquoc

Đây là giải pháp cho phiên bản mới nhất [2.2.0]. Mọi thứ khác trả lại ip máy chủ cho tôi.
Abdul Sadik Yalcin

3

Từ việc đọc mã nguồn socket.io, có vẻ như phương thức "lắng nghe" sẽ lấy các đối số (máy chủ, tùy chọn, fn) và nếu "máy chủ" là một phiên bản của máy chủ HTTP / S, nó sẽ đơn giản bao bọc nó cho bạn.

Vì vậy, bạn có thể cung cấp cho nó một máy chủ trống để lắng nghe sự kiện 'kết nối' và xử lý ổ cắm điều khiển từ xa; tuy nhiên, mọi thứ có thể rất khó khăn nếu bạn cần liên kết địa chỉ đó với một đối tượng socket.io thực tế.

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

Có thể dễ dàng hơn để gửi một bản vá cho socket.io trong đó đối tượng Socket riêng của họ được mở rộng với thuộc tính RemoteAddress được gán tại thời điểm kết nối ...


Bản vá này rất có thể sẽ được bao gồm trong bản phát hành tiếp theo github.com/LearnBoost/Socket.IO-node/pull/286
mak

3

Rất dễ. Đặt đầu tiên

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

console.log(socket);

Bạn sẽ thấy tất cả các lĩnh vực của ổ cắm. sau đó sử dụng CTRL + F và tìm kiếm địa chỉ từ. Cuối cùng, khi bạn tìm thấy trường RemoteAddress, hãy sử dụng dấu chấm để lọc dữ liệu. trong trường hợp của tôi nó là

console.log(socket.conn.remoteAddress);

Hôm nay tôi tìm thấy giải pháp tương tự trong một vấn đề tương tự!
Filippo1980

Điều này không cung cấp IP của điểm cuối của khách hàng. Trong trường hợp của tôi, nó chỉ trả về IP của máy chủ proxy ngược.
Akseli Palén

3

Trong socket.io 2.0 : bạn có thể sử dụng:

socket.conn.transport.socket._socket.remoteAddress

làm việc với transports: ['websocket']


3

Điều này hoạt động cho phiên bản 2.3.0 mới nhất :

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

2

trên socket.io1.3.4 bạn có các khả năng sau.

socket.handshake.address,

socket.conn.remoteAddress hoặc là

socket.request.client._peername.address


2

Trong phiên bản v2.3.0

công việc này đối với tôi:

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

1

sử dụng socket.request.connection.remoteAddress


4
Kể từ phiên bản 1.3.7, điều này trở lại::ffff:127.0.0.1
dmr07

1

Phiên bản mới nhất hoạt động với:

console.log(socket.handshake.address);

5
Kể từ phiên bản 1.3.7, điều này trở lại::ffff:127.0.0.1
dmr07

tương tự 1.4.8 :: ffff: 10.0.0.7
Xin

1
@ dmr07 đây là phiên bản IPv6. Bạn có thể buộc IPv4 bằng cách làm cho máy chủ http lắng nghe 0.0.0.0. Liên quan: stackoverflow.com/a/37378670/5138796
darrachequesne

bạn có thể làm console.log (socket.handshake.address.subopes (7)) nó sẽ chỉ in ip 127.0.0.1
node_man

1

Chào mừng năm 2019, nơi bản thảo từ từ chiếm lĩnh thế giới. Các câu trả lời khác vẫn hoàn toàn hợp lệ. Tuy nhiên, tôi chỉ muốn cho bạn thấy làm thế nào bạn có thể thiết lập điều này trong một môi trường đánh máy.

Trong trường hợp bạn chưa có. Trước tiên bạn nên cài đặt một số phụ thuộc (tức là từ dòng lệnh 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"
  }

Tôi đã xác định nhập khẩu bằng cách nhập ES6 (trước tiên bạn nên bật tsconfig.jsontệp của mình .)

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

Bởi vì tôi sử dụng bản thảo nên tôi đã gõ đầy đủ, trên mọi thứ tôi làm với các đối tượng này.

Vì vậy, rõ ràng, trước tiên bạn cần một máy chủ http:

const handler = express();

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

Tôi đoán bạn đã làm tất cả điều đó. Và có lẽ bạn đã thêm socket io vào nó:

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

Tiếp theo, để xử lý các kết nối socket-io mới, bạn có thể đặt SocketIO.Socketloại trên tham số của nó.

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

Và cuối cùng, vì bây giờ chúng ta đã gõ đầy đủ, chúng ta có thể dễ dàng lấy ip từ ổ cắm của mình mà không cần đoán:

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

-1

Trong 1.3.5:

var clientIP = socket.handshake.headers.host;

5
Kể từ phiên bản 1.3.7, điều này trả về url trang, không phải ip
dmr07
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.