【问题标题】:Get the client's IP address in socket.io在socket.io中获取客户端的IP地址
【发布时间】:2011-09-21 10:23:51
【问题描述】:

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

【问题讨论】:

  • 有点切线,但 console.cat(socket) 可能通过递归地将套接字对象中的所有内容转储到控制台上来帮助
  • @izb 好点,但console.dir(socket) 可能是你的意思
  • 对于 Socket 4.2.0+ 的解决方案似乎不起作用

标签: node.js ip-address socket.io


【解决方案1】:

通过阅读 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 属性进行扩展...

【讨论】:

【解决方案2】:

Socket.IO 0.7.7 版现在声称返回客户端的 IP 地址。 我取得了成功:

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

【讨论】:

  • 它的client.conn.remoteAddress;在较新的版本中。
【解决方案3】:

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

【讨论】:

  • 嗯...因为他的是 .connection.remoteAddress 而我的是 .handshake.address?
  • @GarciadelCastillo 您可能在代理后面。试试这个:stackoverflow.com/a/11187053/971459
  • 在 v1.0 中不起作用——它只是为我记录主机的地址。
  • socket.request.connection.remoteAddress 1.x 版本
  • 我在本地电脑上试过这个,但我收到New connection from undefined:undefined
【解决方案4】:

这似乎有效:

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.request.connection.remoteAddress
  • 请提供您使用的Socket.io版本。
【解决方案5】:

对于 1.0.4:

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

  console.log(clientIp);
});

【讨论】:

  • 你从哪里得到的信息?我以为我已经阅读了 socket.io 的所有文档,但没有看到这个。它完美地解决了我与 OP 类似的问题。
  • 只是console.log socket 来查看所有可用信息,我相信它会不断变化,因为它没有记录。
  • 在 v1.2.1 中,socket.request.connection.remoteAddresssocket.request.connection.remotePort 为我工作。但是,当我尝试时,我没有看到列出的这些属性中的任何一个:console.log(util.inspect(socket.request.connection, {showHidden: true, colors: true})); 为什么不呢?
  • 也适用于 1.3.4。谢谢
  • 从版本1.3.7开始,返回::ffff:127.0.0.1
【解决方案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);

【讨论】:

  • 我正要试试那个握手代码,谢谢指出它没用!!
  • “最新的socket.io版本”是什么意思?请提供具体版本。
  • 2014 年 7 月的最新版本
  • Socket.io 3.0 的答案是什么?
【解决方案7】:

使用socket.request.connection.remoteAddress

【讨论】:

  • 从版本1.3.7开始,返回::ffff:127.0.0.1
【解决方案8】:

使用最新的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']);

}

【讨论】:

    【解决方案9】:

    从 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

    【讨论】:

    • 也与 1.3.3 确认。
    • @Rachael @ Codesleuth 感谢您对版本的确认,非常感谢。我得到了一些支持,所以我想这仍然有效,但我还没有测试过自己。
    【解决方案10】:

    在 1.3.5 中:

    var clientIP = socket.handshake.headers.host;
    

    【讨论】:

    • 1.3.7 版本开始,这将返回页面 url,而不是 ip
    【解决方案11】:

    很容易。 先放

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

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

    console.log(socket.conn.remoteAddress);
    

    【讨论】:

    • 今天我在类似的事情中找到了相同的解决方案!
    • 这不会给出客户端端点的 IP。在我的例子中,它只返回反向代理服务器的 IP。
    【解决方案12】:

    最新版本适用于:

    console.log(socket.handshake.address);
    

    【讨论】:

    • 从版本1.3.7开始,返回::ffff:127.0.0.1
    • 类似 1.4.8 ::ffff:10.0.0.7
    • @dmr07 这是 IPv6 版本。您可以通过使 http 服务器侦听 0.0.0.0 来强制 IPv4。相关:stackoverflow.com/a/37378670/5138796
    • 你可以做 console.log(socket.handshake.address.substring(7)) 它只会打印 ip 127.0.0.1
    【解决方案13】:

    我发现在 socket.handshake.headers 中有一个 forwarded for 地址,它没有出现在我的本地计算机上。我能够使用以下方法获取远程地址:

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

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

    【讨论】:

    • 我尝试过的所有其他内容都返回了::ffff:127.0.0.1,但这给了我实际的 IP
    • 爱你,所有其他答案都给我回送 ip,只有这个标头有效!
    • 这是最新版本[2.2.0]的解决方案。其他一切都为我返回了服务器 ip。
    【解决方案14】:

    socket.io 1.3.4 你有以下可能性。

    socket.handshake.address,

    socket.conn.remoteAddress

    socket.request.client._peername.address

    【讨论】:

      【解决方案15】:

      如果您使用其他服务器作为反向代理,所有提到的字段都将包含 localhost。最简单的解决方法是在代理服务器中为 ip/port 添加标头。

      nginx 示例: 在你的proxy_pass之后添加这个:

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

      这将使 headers 在 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。

      【讨论】:

      • 这是最好的解决方案,如果 nodejs 在代理后面,其他答案都不起作用
      • @zuim 先生,你是我的英雄!
      【解决方案16】:

      在socket.io 2.0中:你可以使用:

      socket.conn.transport.socket._socket.remoteAddress

      适用于transports: ['websocket']

      【讨论】:

        【解决方案17】:

        v2.3.0

        版本中

        这对我有用:

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

        【讨论】:

          【解决方案18】:

          欢迎来到 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}`);
          

          【讨论】:

            【解决方案19】:

            这适用于 2.3.0 版本:

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

            【讨论】:

              【解决方案20】:

              以下是获取客户端 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。完成后,它应该会为您提供客户的准确位置,这意味着它有效。

              【讨论】:

                【解决方案21】:

                我的情况

                我改变我的

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

                【讨论】:

                  【解决方案22】:

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

                  我尝试了socket.handshake.address,它有效,但前缀为 ::ffff:

                  我不得不使用正则表达式来删除它。

                  这适用于版本 4.0.1

                  socket.conn.remoteAddress
                  

                  【讨论】:

                  • 这会为我返回::1
                  • 是的,这就是我在给出的解决方案中所说的。您所要做的就是使用正则表达式或 3ven Javascript 切片从您想要的信息中删除该部分。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-12-20
                  • 1970-01-01
                  • 2019-01-14
                  • 2019-11-13
                  • 1970-01-01
                  • 2013-07-07
                  • 2011-05-26
                  相关资源
                  最近更新 更多