在 socket.io 中获取客户端的 IP 地址

在 Node.js 服务器中使用 socket.IO 时,是否有一种简单的方法来获取传入连接的 IP 地址?我知道您可以从标准的 HTTP 连接获得它,但是 socket.io 有点不同。

175460 次浏览

通过阅读 socket.io 源代码,看起来“ listen”方法接受参数(server、 options、 fn) ,如果“ server”是 HTTP/S 服务器的一个实例,它将简单地为您包装它。

因此,您可以假设给它一个空服务器,该服务器侦听“ connect”事件并处理套接字 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 的0.7.7版本声明返回客户端的 IP 地址。 我在以下方面取得了成功:

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

好的,从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);
});

这似乎行得通:

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.0.4:

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


console.log(clientIp);
});

用于最新的 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);

使用 socket.request.connection.remoteAddress

使用最新的 1.0.6版本的 Socket.IO,并将我的应用程序部署在 Heroku上,我使用 headers将客户机 IPport放入 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.io1.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 的未来版本中可以工作。

也可以看看这个相关链接: 引擎问题

在1.3.5:

var clientIP = socket.handshake.headers.host;

很简单。 先放

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


console.log(socket);

您将看到套接字的所有字段。然后使用 CTRL + F 并搜索单词地址。 最后,当您找到字段 RemoteAddress 时,使用点来过滤数据。 对我来说是的

console.log(socket.conn.remoteAddress);

最新版本的工作原理如下:

console.log(socket.handshake.address);

我发现在 socket.handshake.headers 中有一个 转发地址,它没有出现在我的本地机器上。我可以通过以下方式得到远程地址:

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

这是在服务器端,而不是客户端。

socket.io1.3.4上,有以下可能性。

socket.handshake.address,

socket.conn.remoteAddress

socket.request.client._peername.address

如果您使用其他服务器作为反向代理,则上述所有字段都将包含 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 2.0中,您可以使用:

socket.conn.transport.socket._socket.remoteAddress

transports: ['websocket']合作

在版本 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);

我想这些你都做过了。 而且你可能已经给它添加了套接字 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}`);

这适用于 2.3.0版本:

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

以下是获取客户 IP 地址的方法(v3.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();

只是为了检查它是否有效,请访问 < a href = “ http://geoplugin.net/json.gsp? ip =”rel = “ nofollow norefrer”> geoplugin.net/json.gsp?ip= 一定要切换链接中的 IP 地址。在你这样做之后,它应该给你客户端的准确位置,这意味着它的工作。

为了我的案子

我改变了我的

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()
]}
}

我浏览了博客文章,甚至人们对这个问题的回答。

我尝试了 socket.handshake.address和它的工作,但以 校对: ffff 校对: ffff 校对: ffff 校对: ffff 校对: ffff 校对: ffff 校对: ffff 校对: ffff 校对: ffff 校对: ffff 校对: ffff 校对: ffff 校对: ff为前缀

我必须使用 regex 来删除它。

这适用于 4.0.1版本

socket.conn.remoteAddress