3

私はweb ソケット サーバーの nodejs でwsモジュールを使用しています。コードの簡略化されたバージョンは次のとおりです。

var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({port: 9001});

wss.on('connection', function (ws) {

    // is the ws object created here ?

  ws.on('message', function (message) {
    if (message[0] === '+') {
        ws.name = message.substring(1);
        console.log(ws.name+' connected');
    }
  });

  ws.on('close', function () {
    console.log(ws.name+' disconnected');
    // Will this ws object be deleted ?
  });
});

私が知りたいのですが:

  • 接続の各イベントで、ws オブジェクトが作成されますか?
  • ガベージ コレクションが行われるまで、接続されたクライアントごとにこのオブジェクトの 1 つが RAM に保持されますか?

そして最も重要なことは、大量のクライアントが切断され、ガベージ コレクションが行われるまで ws オブジェクトが横たわっている場合、ガベージ コレクションが発生すると、サーバーがかなりの時間ロックされる可能性があることです。これらの ws オブジェクトを別のオブジェクトに格納するという問題を解決する必要があるので、delete キーワードを使用して、close イベントを取得したらすぐにそれらを削除できますか?

私がそうするなら、私の可能性は次のようになります:

var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({port: 9001});

var websockets = {};

wss.on('connection', function (ws) {
  ws.on('message', function (message) {
    if (message[0] === '+') {
        ws.name = message.substring(1);
        websockets[ws.name] = ws; // Add to the object that stores ws objects
        console.log(ws.name+' connected');
    }
  });

  ws.on('close', function () {
    delete websockets[ws.name]; // Delete from the object
    console.log(ws.name+' disconnected');
  });
});

それで、それは価値がありますか?2 番目のスニペットで、よりガベージ コレクションに適したコードを書いていますか? ガベージ コレクションが発生したときに、長時間のロックアップを回避するのに役立ちますか?

更新: 申し訳ありませんが、コードの 2 番目のスニペットがいかに愚かであるかに気付きました。私は実際にオブジェクトの量を複製していwebsockets[ws.name] = wsます...しかし、質問の最初の部分はまだ有効です。

4

1 に答える 1

5

接続の各イベントで、ws オブジェクトが作成されますか?

はい。

ガベージ コレクションが行われるまで、接続されたクライアントごとにこのオブジェクトの 1 つが RAM に保持されますか?

はい、これはすべてのJavaScript オブジェクトに当てはまります。

これらの ws オブジェクトを別のオブジェクトに格納する手間を省く必要があるので、delete キーワードを使用して、close イベントを取得したらすぐにそれらを削除できますか?

いいえdelete。キーワードを使用してもメモリは解放されません。実際には、参照を削除するだけです。次の例を検討してください。

var x = { };
var y = { };
var z = { };
x.test = z;
y.test = z;
delete x.test;

ご覧のとおりx.test、 は削除されます (オブジェクトには属性がxなくなります) が、 への参照を保持しているため、まったく削除されません。.testzyz

wsまた、WS は複数のオブジェクトをどのように処理できると思いますか? それらを内部のどこかに保存します。オブジェクトを削除したい場合wsは、単に

ws.on('close', function () {
    delete ws;
});

これにより、ある時点でガベージ コレクタが収集することが保証されwsます。一方で、WSこれはすでに内部で処理されていると思いますので、まったく心配する必要はありません。

補足: JavaScript でガベージ コレクターをトリガーする方法はありません。しかし、それについて心配する必要はありません。メモリの上限に達すると、自動的に起動します。

于 2012-08-16T06:51:54.623 に答える