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.
console.dir(socket)
có thể là ý của bạn
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.
console.dir(socket)
có thể là ý của bạn
Câu trả lời:
Đượ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);
});
1.3.7
, điều này trở lại::ffff:127.0.0.1
socket.request.connection.remoteAddress
cho phiên bản 1.x
cho 1.0.4:
io.sockets.on('connection', function (socket) {
var socketId = socket.id;
var clientIp = socket.request.connection.remoteAddress;
console.log(clientIp);
});
socket.request.connection.remoteAddress
và socket.request.connection.remotePort
là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?
1.3.7
, điều này trở lại::ffff:127.0.0.1
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.
Đố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);
Sử dụng 1.0.6
phiên bản mới nhất Socket.IO
và ứng dụng của tôi được triển khai Heroku
, tôi nhận ứng dụng khách IP
và port
sử dụng headers
và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']);
}
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
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;
}
Đ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);
});
127.0.0.1
cho tôi, không phải IP của máy khách (node.js chạy trên máy chủ từ xa).
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.
::ffff:127.0.0.1
nhưng điều này đã cho tôi IP thực tế
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 ...
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);
Đ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);
});
trên socket.io
1.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
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]
Phiên bản mới nhất hoạt động với:
console.log(socket.handshake.address);
1.3.7
, điều này trở lại::ffff:127.0.0.1
0.0.0.0
. Liên quan: stackoverflow.com/a/37378670/5138796
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.json
tệ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.Socket
loạ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}`);
Trong 1.3.5:
var clientIP = socket.handshake.headers.host;
1.3.7
, điều này trả về url trang, không phải ip