เมื่อใช้ socket.IO ในเซิร์ฟเวอร์ Node.js มีวิธีง่ายๆในการรับที่อยู่ IP ของการเชื่อมต่อขาเข้าหรือไม่? ฉันรู้ว่าคุณสามารถรับได้จากการเชื่อมต่อ HTTP มาตรฐาน แต่ socket.io เป็นสัตว์ร้ายที่แตกต่างกันเล็กน้อย
console.dir(socket)อาจเป็นอย่างที่คุณหมายถึง
เมื่อใช้ socket.IO ในเซิร์ฟเวอร์ Node.js มีวิธีง่ายๆในการรับที่อยู่ IP ของการเชื่อมต่อขาเข้าหรือไม่? ฉันรู้ว่าคุณสามารถรับได้จากการเชื่อมต่อ HTTP มาตรฐาน แต่ socket.io เป็นสัตว์ร้ายที่แตกต่างกันเล็กน้อย
console.dir(socket)อาจเป็นอย่างที่คุณหมายถึง
คำตอบ:
โอเค ณ 0.7.7 มีให้ แต่ไม่ใช่ในลักษณะที่ lubar อธิบาย ฉันต้องแยกวิเคราะห์บันทึกการกระทำบน 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);
});
1.3.7นี้จะกลับมา::ffff:127.0.0.1
socket.request.connection.remoteAddressสำหรับรุ่น 1.x
สำหรับ 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และsocket.request.connection.remotePortทำงานให้ฉัน อย่างไรก็ตามฉันไม่เห็นคุณสมบัติเหล่านี้ในรายการเมื่อฉันลอง: console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); ทำไมไม่?
1.3.7นี้จะกลับมา::ffff:127.0.0.1
หากคุณใช้เซิร์ฟเวอร์อื่นเป็นพร็อกซีย้อนกลับฟิลด์ที่กล่าวถึงทั้งหมดจะมี 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 สำหรับฉัน
สำหรับเวอร์ชันล่าสุดของ 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);
เมื่อใช้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']);
}
ตั้งแต่ 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
เวอร์ชัน 0.7.7 ของ Socket.IO อ้างว่าส่งคืนที่อยู่ IP ของไคลเอ็นต์แล้ว ฉันประสบความสำเร็จกับ:
var socket = io.listen(server);
socket.on('connection', function (client) {
var ip_address = client.connection.remoteAddress;
}
ดูเหมือนว่าจะได้ผล:
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ให้ฉันเสมอไม่ใช่ IP ของไคลเอนต์ (node.js ทำงานบนเซิร์ฟเวอร์ระยะไกล)
ฉันพบว่าภายใน socket.handshake.headers มีการส่งต่อสำหรับที่อยู่ซึ่งไม่ปรากฏในเครื่องของฉัน และฉันสามารถรับที่อยู่ระยะไกลโดยใช้:
socket.handshake.headers['x-forwarded-for']
นี่คือในฝั่งเซิร์ฟเวอร์ไม่ใช่ฝั่งไคลเอ็นต์
::ffff:127.0.0.1แต่สิ่งนี้ทำให้ฉันได้ IP จริง
จากการอ่านซอร์สโค้ด socket.io ดูเหมือนว่าเมธอด "listen" จะใช้อาร์กิวเมนต์ (เซิร์ฟเวอร์, ตัวเลือก, fn) และถ้า "เซิร์ฟเวอร์" เป็นอินสแตนซ์ของเซิร์ฟเวอร์ HTTP / S ก็จะรวมมันไว้ให้คุณ
ดังนั้นคุณจึงสามารถให้เซิร์ฟเวอร์ว่างซึ่งรับฟังเหตุการณ์ 'การเชื่อมต่อ' และจัดการกับที่อยู่ของซ็อกเก็ต 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 ที่กำหนดในเวลาเชื่อมต่อ ...
ง่ายมาก. ใส่ครั้งแรก
io.sockets.on('connection', function (socket) {
console.log(socket);
คุณจะเห็นช่องทั้งหมดของซ็อกเก็ต จากนั้นใช้ CTRL + F และค้นหาที่อยู่ของคำ สุดท้ายเมื่อคุณพบฟิลด์ remoteAddress ใช้จุดเพื่อกรองข้อมูล ในกรณีของฉันมันคือ
console.log(socket.conn.remoteAddress);
ใน socket.io 2.0 : คุณสามารถใช้:
socket.conn.transport.socket._socket.remoteAddress
ใช้งานได้กับ transports: ['websocket']
สิ่งนี้ใช้ได้กับเวอร์ชัน2.3.0ล่าสุด:
io.on('connection', socket => {
const ip = socket.handshake.headers[x-forwarded-for] || socket.conn.remoteAddress.split(":")[3];
console.log(ip);
});
บน socket.io 1.3.4 คุณมีความเป็นไปได้ดังต่อไปนี้
socket.handshake.address,
socket.conn.remoteAddress หรือ
socket.request.client._peername.address
ในเวอร์ชันv2.3.0
งานนี้สำหรับฉัน:
socket.handshake.headers['x-forwarded-for'].split(',')[0]
เวอร์ชันล่าสุดใช้งานได้กับ:
console.log(socket.handshake.address);
1.3.7นี้จะกลับมา::ffff:127.0.0.1
0.0.0.0ฟัง ที่เกี่ยวข้อง: stackoverflow.com/a/37378670/5138796
ยินดีต้อนรับปี 2019 ที่ typescript เข้าครอบงำโลกอย่างช้าๆ คำตอบอื่น ๆ ยังคงใช้ได้อย่างสมบูรณ์ อย่างไรก็ตามฉันแค่อยากจะแสดงให้คุณเห็นว่าคุณสามารถตั้งค่านี้ในสภาพแวดล้อมที่พิมพ์ได้อย่างไร
ในกรณีที่คุณยังไม่ได้ทำ ครั้งแรกที่คุณควรติดตั้งการอ้างอิงบางอย่าง
(เช่นจาก 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"
}
ฉันกำหนดการนำเข้าโดยใช้การนำเข้า ES6 (ซึ่งคุณควรเปิดใช้งานในtsconfig.jsonไฟล์ของคุณก่อน)
import * as SocketIO from "socket.io";
import * as http from "http";
import * as https from "https";
import * as express from "express";
เนื่องจากฉันใช้ typescript ฉันจึงพิมพ์เต็มในทุกสิ่งที่ฉันทำกับวัตถุเหล่านี้
ดังนั้นก่อนอื่นคุณต้องมีเซิร์ฟเวอร์ 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.3.5:
var clientIP = socket.handshake.headers.host;
1.3.7นี้จะแสดง url ของเพจไม่ใช่ ip