web-dev-qa-db-ja.com

Nodejsのランダムな空きTCPポート

私のプロジェクトでは、クラスの新しいインスタンスがインスタンス化されるたびに新しいポートをセットアップする必要があります。

Node.jsでは、新しいソケットサーバーに設定する無料のTCPポートを見つける方法を教えてください。または、指定したポートが既に使用されているかどうかを確認します。

28
Marcos Bergamo

ポートに_0_を指定することにより、OSによって割り当てられたランダムな空きポートにバインドできます。このようにして、競合状態の影響を受けません(たとえば、開いているポートと、それにバインドする機会を得る前にそれにバインドされているプロセスを確認します)。

次に、 server.address().port を呼び出して、割り当てられたポートを取得できます。

例:

_var net = require('net');

var srv = net.createServer(function(sock) {
  sock.end('Hello world\n');
});
srv.listen(0, function() {
  console.log('Listening on port ' + srv.address().port);
});
_
44
mscdex

開いているTCPのポートを見つけるには、モジュール portastic を使用できます。

あなたはこのようなポートを見つけることができます:

port = require('portastic');

options = {
    min : 8000,
    max : 8005
}

port.find(options, function(err, data){
    if(err)
        throw err;
    console.log(data);
});
3
Marcos Bergamo

Expressアプリの場合:

const app = require('express')();

const server = app.listen(0, () => {
  console.log('Listening on port:', server.address().port);
});
2
Ninh Pham

移植待ち

OSによって選択されたportに依存するダウンストリームコードを使用して、これを「同期的に」実行しようとしている場合(たとえば、テストサーバーを作成し、ポートをテストに渡すとき )、次のレシピがうまくいきました:

export const sleepForPort = async (httpServer: Server, ms: number): Promise<number> => {
  return new Promise<number>((resolve, reject) => {
    httpServer.listen(0, async () => {
      try{
        let addr = (httpServer.address() as AddressInfo | null)
        while(! (addr && addr.port) ) {
          await sleep(ms);
          addr = httpServer.address() as AddressInfo | null
        }
        resolve(addr.port);
      }catch(e){
        reject(e);
      }
    });
  });
}

const sleep = (ms: number) => {
  return new Promise(resolve => setTimeout(resolve, ms));
}

ライブサーバーに対して統合テストを実行している場合、これにより、ポート番号がawait使用可能になり、testClientがこのポートでlocalhostをヒットできるようにこれを返すことができます。

export const setupTests = async () => {
  const app = createExpressApp(...);
  const httpServer = createServer(app);
  server.installSubscriptionHandlers(httpServer); // Testing graphql subscriptions
  const port = await sleepForPort(httpServer, 100);
  return {port}
}

describe("Http server test", () => {
  let port: number;
  beforeAll(async () => {
    {port} = await setupTests()
  })
  it("Hits the right port", () => {
    const res = await fetch(`http://localhost:${port}/testing`)
    expect(res).toBeDefined()
    expect(res.status).toEqual(200);
  }
})
0
The Aelfinn