简体   繁体   English

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

[英]Get the client's IP address in socket.io

When using socket.IO in a Node.js server, is there an easy way to get the IP address of an incoming connection?在 Node.js 服务器中使用 socket.IO 时,是否有一种简单的方法来获取传入连接的 IP 地址? I know you can get it from a standard HTTP connection, but socket.io is a bit of a different beast.我知道您可以从标准 HTTP 连接获取它,但 socket.io 有点不同。

Okay, as of 0.7.7 this is available, but not in the manner that lubar describes.好的,从 0.7.7 开始,这是可用的,但不是以 lubar 描述的方式。 I ended up needing to parse through some commit logs on git hub to figure this one out, but the following code does actually work for me now:我最终需要解析 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);
});

for 1.0.4:对于 1.0.4:

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

  console.log(clientIp);
});

If you use an other server as reverse proxy all of the mentioned fields will contain localhost.如果您使用其他服务器作为反向代理,则所有提到的字段都将包含 localhost。 The easiest workaround is to add headers for ip/port in the proxy server.最简单的解决方法是在代理服务器中为 ip/port 添加标头。

Example for nginx: add this after your proxy_pass : nginx 示例:在您的proxy_pass之后添加:

proxy_set_header  X-Real-IP $remote_addr;
proxy_set_header  X-Real-Port $remote_port;

This will make the headers available in the socket.io node server:这将使头文件在 socket.io 节点服务器中可用:

var ip = socket.handshake.headers["x-real-ip"];
var port = socket.handshake.headers["x-real-port"];

Note that the header is internally converted to lower case.请注意,标头在内部转换为小写。

If you are connecting the node server directly to the client,如果您将节点服务器直接连接到客户端,

var ip = socket.conn.remoteAddress;

works with socket.io version 1.4.6 for me.适用于我的 socket.io 版本 1.4.6。

For latest socket.io version use对于最新的 socket.io 版本使用

socket.request.connection.remoteAddress

For example:例如:

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

beware that the code below returns the Server's IP, not the Client's IP请注意,下面的代码返回的是服务器的 IP,而不是客户端的 IP

var address = socket.handshake.address;
console.log('New connection from ' + address.address + ':' + address.port);

Using the latest 1.0.6 version of Socket.IO and have my app deployed on Heroku , I get the client IP and port using the headers into the socket handshake :使用最新的1.0.6Socket.IO并将我的应用程序部署在Heroku ,我使用headers获取客户端IPportsocket 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']);

}

This works for the 2.3.0 version:这适用于2.3.0版本:

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

Since socket.io 1.1.0, I use :从 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 }
}

Edit : Note that this is not part of the official API, and therefore not guaranteed to work in future releases of socket.io.编辑:请注意,这不是官方 API 的一部分,因此不能保证在 socket.io 的未来版本中工作。

Also see this relevant link : engine.io issue另请参阅此相关链接: engine.io issue

Version 0.7.7 of Socket.IO now claims to return the client's IP address. Socket.IO 的 0.7.7 版本现在声称返回客户端的 IP 地址。 I've had success with:我在以下方面取得了成功:

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

Very easy.好简单。 First put先放

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

console.log(socket);

You will see all fields of socket.您将看到套接字的所有字段。 then use CTRL+F and search the word address.然后使用 CTRL+F 并搜索单词地址。 Finally, when you find the field remoteAddress use dots to filter data.最后,当您找到字段 remoteAddress 时,使用点来过滤数据。 in my case it is就我而言,它是

console.log(socket.conn.remoteAddress);

I have found that within the socket.handshake.headers there is a forwarded for address which doesn't appear on my local machine.我发现在 socket.handshake.headers 中有一个转发地址,它没有出现在我的本地机器上。 And I was able to get the remote address using:我能够使用以下方法获取远程地址:

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

This is in the server side and not client side.这是在服务器端而不是客户端。

This seems to work:这似乎有效:

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);
});

In socket.io 2.0 : you can use:在 socket.io 2.0 中:您可以使用:

socket.conn.transport.socket._socket.remoteAddress

works with transports: ['websocket']适用于transports: ['websocket']

From reading the socket.io source code it looks like the "listen" method takes arguments (server, options, fn) and if "server" is an instance of an HTTP/S server it will simply wrap it for you.从阅读 socket.io 源代码来看,“listen”方法看起来像接受参数(服务器、选项、fn),如果“服务器”是 HTTP/S 服务器的一个实例,它会简单地为你包装它。

So you could presumably give it an empty server which listens for the 'connection' event and handles the socket remoteAddress;所以你大概可以给它一个空服务器,它监听 'connection' 事件并处理套接字 remoteAddress; however, things might be very difficult if you need to associate that address with an actual socket.io Socket object.但是,如果您需要将该地址与实际的 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));

Might be easier to submit a patch to socket.io wherein their own Socket object is extended with the remoteAddress property assigned at connection time...向 socket.io 提交补丁可能更容易,其中他们自己的 Socket 对象使用在连接时分配的 remoteAddress 属性进行扩展...

on socket.io 1.3.4 you have the following possibilities.socket.io 1.3.4 上,您有以下可能性。

socket.handshake.address , socket.handshake.address ,

socket.conn.remoteAddress or socket.conn.remoteAddress

socket.request.client._peername.address

In version v2.3.0v2.3.0版本中

this work for me :这对我有用:

socket.handshake.headers['x-forwarded-for'].split(',')[0]

Welcome in 2019, where typescript slowly takes over the world.欢迎来到 2019 年,打字稿逐渐占领世界。 Other answers are still perfectly valid.其他答案仍然完全有效。 However, I just wanted to show you how you can set this up in a typed environment.但是,我只是想向您展示如何在类型化环境中进行设置。

In case you haven't yet.如果你还没有。 You should first install some dependencies (ie from the commandline: npm install <dependency-goes-here> --save-dev )您应该首先安装一些依赖项(即从命令行: 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"
  }

I defined the imports using ES6 imports (which you should enable in your tsconfig.json file first.)我使用 ES6 导入定义了导入(您应该首先在tsconfig.json文件中启用它。)

import * as SocketIO from "socket.io";
import * as http from "http";
import * as https from "https";
import * as express from "express";

Because I use typescript I have full typing now, on everything I do with these objects.因为我使用打字稿,所以我现在可以完全打字,对我对这些对象所做的一切。

So, obviously, first you need a http server:所以,很明显,首先你需要一个 http 服务器:

const handler = express();

const httpServer = (useHttps) ?
  https.createServer(serverOptions, handler) :
  http.createServer(handler);

I guess you already did all that.我想你已经做到了这一切。 And you probably already added socket io to it:您可能已经向其中添加了 socket io:

const io = SocketIO(httpServer);
httpServer.listen(port, () => console.log("listening") );
io.on('connection', (socket) => onSocketIoConnection(socket));

Next, for the handling of new socket-io connections, you can put the SocketIO.Socket type on its parameter.接下来,为了处理新的 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(...));
}

And then finally, because we have full typing now, we can easily retrieve the ip from our socket, without guessing:最后,因为我们现在有完整的输入,我们可以轻松地从我们的套接字中检索 ip,而无需猜测:

const ip = socket.conn.remoteAddress;
console.log(`client ip: ${ip}`);

使用socket.request.connection.remoteAddress

最新版本适用于:

console.log(socket.handshake.address);

Here's how to get your client's ip address (v 3.1.0):以下是获取客户端 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();

And just to check if it works go to geoplugin.net/json.gsp?ip= just make sure to switch the ip in the link.只是为了检查它是否有效,请转到geoplugin.net/json.gsp?ip=只需确保在链接中切换 ip。 After you have done that it should give you the accurate location of the client which means that it worked.完成后,它应该为您提供客户端的准确位置,这意味着它有效。

I went through blog posts and even peoples answers to the question.我浏览了博客文章,甚至人们对这个问题的回答。

I tried socket.handshake.address and it worked but was prefixed with ::ffff:我尝试了socket.handshake.address并且它工作了,但以::ffff为前缀

I had to use regex to remove that.我不得不使用正则表达式来删除它。

This works for version 4.0.1这适用于4.0.1

socket.conn.remoteAddress

for my case对于我的情况

i change my我改变我的

app.configure(socketio)

to

app.configure(socketio(function(io) {
 io.use(function (socket, next) {
   socket.feathers.clientIP = socket.request.connection.remoteAddress;
   next();
 });
}));

and i'm able to get ip like this我可以像这样获得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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM