[英]Get the client's IP address in socket.io
在 Node.js 服務器中使用 socket.IO 時,是否有一種簡單的方法來獲取傳入連接的 IP 地址? 我知道您可以從標准 HTTP 連接獲取它,但 socket.io 有點不同。
好的,從 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.0.4:
io.sockets.on('connection', function (socket) {
var socketId = socket.id;
var clientIp = socket.request.connection.remoteAddress;
console.log(clientIp);
});
如果您使用其他服務器作為反向代理,則所有提到的字段都將包含 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
,我使用headers
獲取客戶端IP
和port
到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']);
}
這適用於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.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 issue
Socket.IO 的 0.7.7 版本現在聲稱返回客戶端的 IP 地址。 我在以下方面取得了成功:
var socket = io.listen(server);
socket.on('connection', function (client) {
var ip_address = client.connection.remoteAddress;
}
好簡單。 先放
io.sockets.on('connection', function (socket) {
console.log(socket);
您將看到套接字的所有字段。 然后使用 CTRL+F 並搜索單詞地址。 最后,當您找到字段 remoteAddress 時,使用點來過濾數據。 就我而言,它是
console.log(socket.conn.remoteAddress);
我發現在 socket.handshake.headers 中有一個轉發地址,它沒有出現在我的本地機器上。 我能夠使用以下方法獲取遠程地址:
socket.handshake.headers['x-forwarded-for']
這是在服務器端而不是客戶端。
這似乎有效:
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);
});
在 socket.io 2.0 中:您可以使用:
socket.conn.transport.socket._socket.remoteAddress
適用於transports: ['websocket']
從閱讀 socket.io 源代碼來看,“listen”方法看起來像接受參數(服務器、選項、fn),如果“服務器”是 HTTP/S 服務器的一個實例,它會簡單地為你包裝它。
所以你大概可以給它一個空服務器,它監聽 'connection' 事件並處理套接字 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 屬性進行擴展...
在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]
歡迎來到 2019 年,打字稿逐漸占領世界。 其他答案仍然完全有效。 但是,我只是想向您展示如何在類型化環境中進行設置。
如果你還沒有。 您應該首先安裝一些依賴項(即從命令行: 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";
因為我使用打字稿,所以我現在可以完全打字,對我對這些對象所做的一切。
所以,很明顯,首先你需要一個 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}`);
使用socket.request.connection.remoteAddress
最新版本適用於:
console.log(socket.handshake.address);
以下是獲取客戶端 IP 地址 (v 3.1.0) 的方法:
// Current Client
const ip = socket.handshake.headers["x-forwarded-for"].split(",")[1].toString().substring(1, this.length);
// Server
const ip2 = socket.handshake.headers["x-forwarded-for"].split(",")[0].toString();
只是為了檢查它是否有效,請轉到geoplugin.net/json.gsp?ip=只需確保在鏈接中切換 ip。 完成后,它應該為您提供客戶端的准確位置,這意味着它有效。
我瀏覽了博客文章,甚至人們對這個問題的回答。
我嘗試了socket.handshake.address
並且它工作了,但以::ffff為前綴:
我不得不使用正則表達式來刪除它。
這適用於4.0.1版
socket.conn.remoteAddress
對於我的情況
我改變我的
app.configure(socketio)
到
app.configure(socketio(function(io) {
io.use(function (socket, next) {
socket.feathers.clientIP = socket.request.connection.remoteAddress;
next();
});
}));
我可以像這樣獲得ip
function checkIP() {
return async context => {
context.data.clientIP = context.params.clientIP
}
}
module.exports = {
before: {
all: [],
find: [
checkIp()
]}
}
在 1.3.5 中:
var clientIP = socket.handshake.headers.host;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.