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

时间:2011-06-23 17:22:05

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

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

22 个答案:

答案 0 :(得分:151)

好的,从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 :(得分:67)

for 1.0.4:

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

  console.log(clientIp);
});

答案 2 :(得分:37)

如果您使用其他服务器作为反向代理,则所有提到的字段都将包含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。

答案 3 :(得分:20)

有关最新的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);

答案 4 :(得分:8)

使用最新1.0.6Socket.IO并将我的应用部署在Heroku上,我使用{{1}获取客户IPport进入headers

socket handshake

答案 5 :(得分:5)

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

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

答案 6 :(得分:5)

从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

答案 7 :(得分: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);
});

答案 8 :(得分:4)

从读取socket.io源代码看起来,“listen”方法接受参数(服务器,选项,fn),如果“server”是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属性进行扩展...

答案 9 :(得分:3)

很简单。 先放

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

console.log(socket);

您将看到套接字的所有字段。然后使用CTRL + F并搜索字地址。 最后,当您找到字段remoteAddress时,使用点来过滤数据。 就我而言,它是

console.log(socket.conn.remoteAddress);

答案 10 :(得分:3)

在socket.io 2.0 :您可以使用:

socket.conn.transport.socket._socket.remoteAddress

适用于transports: ['websocket']

答案 11 :(得分:3)

我发现在socket.handshake.headers中有一个转发地址,这个地址没有出现在我的本地机器上。我可以使用以下方式获取远程地址:

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

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

答案 12 :(得分:2)

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

socket.handshake.address

socket.conn.remoteAddress

socket.request.client._peername.address

答案 13 :(得分:1)

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

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

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

这适用于 4.0.1

版本
socket.conn.remoteAddress

答案 14 :(得分:1)

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

答案 15 :(得分:1)

最新版本适用于:

console.log(socket.handshake.address);

答案 16 :(得分:1)

在1.3.5中:

var clientIP = socket.handshake.headers.host;

答案 17 :(得分:1)

使用socket.request.connection.remoteAddress

答案 18 :(得分:0)

在版本 v2.3.0

这对我有用:

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

答案 19 :(得分: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}`);

答案 20 :(得分:0)

这适用于最新的 2.3.0 版本:

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

答案 21 :(得分:0)

对于我的情况

我改变我的

Sub sSplitData()
    On Error GoTo E_Handle
    Dim db As DAO.Database
    Dim rsIn As DAO.Recordset
    Dim rsOut As DAO.Recordset
    Dim strData As String
    Dim astrData() As String
    Set db = CurrentDb
    Set rsIn = db.OpenRecordset("SELECT DataIn FROM tblDataIn;")
    If Not (rsIn.BOF And rsIn.EOF) Then
        Set rsOut = db.OpenRecordset("SELECT * FROM tblDataOut WHERE 1=2;")    '    open a recordset that has no records selected for speed
        Do
            strData = rsIn!DataIn
            strData = Mid(strData, 4)   ' get rid of the "fp(" at the start
            strData = Left(strData, Len(strData) - 2)   '   get rid of the ")." at the end
            astrData = Split(strData, ",")  '   split the data based on commas
            With rsOut
                .AddNew
                ![Zug Nr] = astrData(0)
                !Zeit = astrData(1)
                !Stadt = astrData(2)
                ![AB/AN] = astrData(3)
                .Update
            End With
            rsIn.MoveNext
        Loop Until rsIn.EOF
    End If
sExit:
    On Error Resume Next
    rsIn.Close
    rsOut.Close
    Set rsIn = Nothing
    Set rsOut = Nothing
    Set db = Nothing
    Exit Sub
E_Handle:
    MsgBox Err.Description & vbCrLf & vbCrLf & "sSplitData", vbOKOnly + vbCritical, "Error: " & Err.Number
    Resume sExit
End Sub

app.configure(socketio)

我可以这样获取ip

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