Node.jsサーバーでsocket.IOを使用する場合、着信接続のIPアドレスを取得する簡単な方法はありますか?標準のHTTP接続から取得できることは承知していますが、socket.ioは少し違った獣です。
console.dir(socket)
ですが、あなたが意図したことかもしれません
Node.jsサーバーでsocket.IOを使用する場合、着信接続のIPアドレスを取得する簡単な方法はありますか?標準のHTTP接続から取得できることは承知していますが、socket.ioは少し違った獣です。
console.dir(socket)
ですが、あなたが意図したことかもしれません
回答:
わかりました、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.3.7
、これは次を返します::ffff:127.0.0.1
socket.request.connection.remoteAddress
1.xバージョンの場合
1.0.4の場合:
io.sockets.on('connection', function (socket) {
var socketId = socket.id;
var clientIp = socket.request.connection.remoteAddress;
console.log(clientIp);
});
socket.request.connection.remoteAddress
、socket.request.connection.remotePort
私のために働いています。ただし、試したときにこれらのプロパティのいずれも表示されconsole.log(util.inspect(socket.request.connection, {showHidden: true, colors: true}));
ませんでした。なぜですか?
1.3.7
、これは次を返します::ffff:127.0.0.1
他のサーバーをリバースプロキシとして使用する場合、上記のすべてのフィールドに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
て、私はクライアントを取得IP
し、port
使用headers
には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.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の問題
Socket.IOのバージョン0.7.7は、クライアントのIPアドレスを返すように要求します。私は成功しました:
var socket = io.listen(server);
socket.on('connection', function (client) {
var ip_address = client.connection.remoteAddress;
}
これはうまくいくようです:
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.handshake.headers内に、ローカルマシンに表示されない転送先アドレスがあることを発見しました。そして、私は使用してリモートアドレスを取得することができました:
socket.handshake.headers['x-forwarded-for']
これはサーバー側であり、クライアント側ではありません。
::ffff:127.0.0.1
が、これは私に実際のIPを与えました
socket.ioソースコードを読み取ると、「listen」メソッドは引数(サーバー、オプション、fn)を受け取るように見え、「server」がHTTP / Sサーバーのインスタンスである場合は、単純にラップされます。
したがって、おそらく '接続'イベントをリッスンし、ソケットの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オブジェクトが接続時に割り当てられたremoteAddressプロパティで拡張されているsocket.ioにパッチを送信する方が簡単かもしれません...
非常に簡単。最初に置く
io.sockets.on('connection', function (socket) {
console.log(socket);
ソケットのすべてのフィールドが表示されます。次に、CTRL + Fを使用してワードアドレスを検索します。最後に、フィールドremoteAddressが見つかったら、ドットを使用してデータをフィルタリングします。私の場合は
console.log(socket.conn.remoteAddress);
バージョンv2.3.0
私のためのこの仕事:
socket.handshake.headers['x-forwarded-for'].split(',')[0]
最新バージョンは以下で動作します:
console.log(socket.handshake.address);
1.3.7
、これは次を返します::ffff:127.0.0.1
0.0.0.0
。関連:stackoverflow.com/a/37378670/5138796
typescriptがゆっくりと世界を引き継ぐ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";
私はtypescriptを使用しているので、完全なタイピングができるようになりました。
したがって、明らかに、最初に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}`);