เมื่อใช้ 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