Giter Club home page Giter Club logo

get-port's Introduction

get-port

Get an available TCP port.

Install

npm install get-port

Usage

import getPort from 'get-port';

console.log(await getPort());
//=> 51402

Pass in a preferred port:

import getPort from 'get-port';

console.log(await getPort({port: 3000}));
// Will use 3000 if available, otherwise fall back to a random port

Pass in an array of preferred ports:

import getPort from 'get-port';

console.log(await getPort({port: [3000, 3001, 3002]}));
// Will use any element in the preferred ports array if available, otherwise fall back to a random port

Use the portNumbers() helper in case you need a port in a certain range:

import getPort, {portNumbers} from 'get-port';

console.log(await getPort({port: portNumbers(3000, 3100)}));
// Will use any port from 3000 to 3100, otherwise fall back to a random port

API

getPort(options?)

Returns a Promise for a port number.

options

Type: object

port

Type: number | Iterable<number>

A preferred port or an iterable of preferred ports to use.

exclude

Type: Iterable<number>

Ports that should not be returned.

You could, for example, pass it the return value of the portNumbers() function.

host

Type: string

The host on which port resolution should be performed. Can be either an IPv4 or IPv6 address.

By default, it checks availability on all local addresses defined in OS network interfaces. If this option is set, it will only check the given host.

portNumbers(from, to)

Generate port numbers in the given range from...to.

Returns an Iterable for port numbers in the given range.

from

Type: number

The first port of the range. Must be in the range 1024...65535.

to

Type: number

The last port of the range. Must be in the range 1024...65535 and must be greater than from.

Beware

There is a very tiny chance of a race condition if another process starts using the same port number as you in between the time you get the port number and you actually start using it.

Race conditions in the same process are mitigated against by using a lightweight locking mechanism where a port will be held for a minimum of 15 seconds and a maximum of 30 seconds before being released again.

Related

get-port's People

Contributors

acostalima avatar arthurvr avatar bendingbender avatar coreyfarrell avatar davidmarkclements avatar djmadeira avatar floatdrop avatar jonahsnider avatar mastrzyz avatar mihkeleidast avatar mjgallag avatar nagen010 avatar nodkz avatar ntwb avatar richienb avatar samverschueren avatar sebald avatar sindresorhus avatar stroncium avatar wmzy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

get-port's Issues

Exclude port option

Say you have a list of statically assigned ports associated with apps that may be running or not running.

If you start an app that is not already assigned, you want a new port, but one that is not already in your list.

So an option exclude would resolve this, which is much better than the workaround of manually specifying an array of include ports.

Default port?

Any interest in accepting a PR to support passing in a preferred/default port?

Feature request: Available port for any localhost host (localhost, 0.0.0.0, 127.0.0.1)

If server.listen is used with a host, then get-port only returns the correct result if the same host value is provided.

// Some other project running on your machine:
server.listen(3000, 'localhost', cb);

This works, because we put in the host localhost, matching above:

// Your project:
await getPort({ port: 3000, host: 'localhost' }) 
// => Random port that is not bound to localhost, good!

However, when you don't know what host was used in the other project, or what host will be used in yours, you could be in trouble:

// Some other project running on your machine:
server.listen(3000, 'localhost', cb);

// Your project does one of these:

await getPort({ port: 3000 }) 
// => 3000...

await getPort({ port: 3000, host: '0.0.0.0' }) 
// => 3000...

await getPort({ port: 3000, host: '127.0.0.1' }) 
// => 3000...

await getPort({ port: 3000, host: '::' }) 
// => 3000...

If that 3000 port is then used later in your code with localhost, it will fail.

This might be a deficiency or feature in libev, or I'm not understanding how port binding works when the host is provided.

Workaround 1

Always use the same host when creating your server as used when running get-port. I'm finding that to not always be feasible.

Workaround 2

Math.max(
  await getPort({ port: 3000, host: 'localhost' }),
  await getPort({ port: 3000, host: '0.0.0.0' })
);
// => Will always be a random port, even if 3000 is available, 
// because `lockedPorts` ignores the `host`, so one of the two 
// getPort calls will think 3000 is already locked and return a random port.

Potential solution?

Maybe a possible workaround is to allow for passing in an array of hosts, or an option to check all localhost variants?

Does not assign a random port if the desired port is unavailable

Hello.

I am experiencing a issue.
If I have a server running on e.g http://localhost:8080, the following code still assigns me port 8080 instead of a random port:

const getPort = require('get-port');

async function getRandomPort (preferredPort = 8080) {
  const port = await getPort({ port: preferredPort });
  return port;
}

getRandomPort(8080).then(port => console.log(port)); // 8080

getPort.makeRange clashing when running parallel tests

I'm using ava to set up multiple CDCT tests starting with this:

const test = require('ava')
const getPort = require('get-port')
const { Pact } = require('@pact-foundation/pact')

...

test.before('async() => {
  port = await getPort()
  console.log(`Setting up port ${port}`)

  provider = new Pact({
    port,
    ...
  })

  await provider.setup()
})

...

Works great, tests are running in parallel and different ports are used:

Setting up on port 64873
Setting up on port 64874

But Pact gives me a warning saying I'm using a port outside it's recommended range:

WARN: [email protected]/90509 on MBP.localdomain: Like a Boss, you used a port outside of the recommended range (1024 to 49151); I too like to live dangerously.

While it's just a warning, it's still not nice, so I change it to this:

test.before('async() => {
  port = await getPort({ port: getPort.makeRange(1024, 49151) })
  console.log(`Setting up port ${port}`)
  ...
})

But then both end up to be on the same port and my tests fail

Setting up on port 1024
Setting up on port 1024

Could the makeRange be randomized the same way as the default behaviour is?

Race condition

It seems there is a chance for race conditions.
In the time between getPort and the real use of the port (most probably another listen on the same port) it is possible that another process takes the port and it is no longer free.
At least this should be highlighted in the documentation.

(0 , _getPort.portNumbers) is not a function

When I run the below code in an Electron app

import getPort, { portNumbers } from 'get-port';
const port = (await getPort({ port: portNumbers(7092, 65535) })).toString();

I encountered the problem (0 , _getPort.portNumbers) is not a function
9A724661-9408-41d0-9251-1C8AB82DA8A2

TypeError: interval.unref is not a function

When I run await getPort() in an Electron app (dev) I get the following error:

Uncaught (in promise) TypeError: interval.unref is not a function
	if (interval === undefined) {
		interval = setInterval(() => {
			lockedPorts.old = lockedPorts.young;
			lockedPorts.young = new Set();
		}, releaseOldLockedPortsIntervalMs);

		interval.unref(); <----- HERE
	}

UDP ports do also exist

The author of this module may want to clarify in the README / API that get-port is just valid for getting a free TCP port.

Yes, this is Node.js and in Node.js all is about HTTP and stuff on top of HTTP. But UDP does also exist.

Thanks.

Node defaults to ipv6 for port resolution

We noticed that get-port is defaulting to ipv6 for port resolution, which is giving false positives. i.e. given a default port, it comes back as available, where it is actually not available.

We will add more info to this issue shortly - Right now, we need an issue link for tracking purposes.

Get multiple ports via `number` option

I'd like to get two or more free ports in the full range of ports with the assignment mechanism than getPort().

Now there is getPort.makeRange(1024, 65535) and calling .next() multiple times achieves a similar result but it's not exactly the same as getPort() because ports are assigned sequentially from the start argument.

I'd suggest a number option that that if passed changes the signature of the return value to an Array of port.

Possible portNumbers argument validation bug?

get-port/index.js

Lines 163 to 165 in 50e24f6

if (to < minPort || to > maxPort + 1) {
throw new RangeError(`'to' must be between ${minPort} and ${maxPort + 1}`);
}

Is this + 1 logic correct?

If you run this snippet:

import { portNumbers } from 'get-port';

console.log([...portNumbers(65535, 65536)]);

You get the output

[ 65535, 65536 ]

The maximum port number should be 65,535 but the argument validation seems to allow the value 65536 to be returned.

If this is a bug I'd be happy to PR it.

Preferred port range?

Issuehunt badges

Would be nice to see an option to provide a preferred range, rather than array of ports.

console.log(
  await getPort({port: 
    { 
      from: 4000,
      to: 5000
    }
  })
);

stroncium earned $30.00 by resolving this issue!

Portnumber Range Doesnot support in ServerSide

I'm trying to use the server with multiple ports and dynamic response to get the port number within the range of port numbers
but they didn't support it on the server side.

get-port version->6.1.2

const getPort = require('get-port');
const {portNumbers} = require('portNumbers')
async ()=>{
    console.log(await getPort({port: portNumbers(5000, 6000)}));
}

I'm trying on

import getPort, {portNumbers} from 'get-port';

but the import module doesn't support on nodejs server, the only use of require method

Does anyone Have an idea?

Allow a validation function

Instead of checking if a file exists, we just try to open it.
So, instead of searching for a port, try to use the port and try another if it fails.

So, for example:

import express from 'express';
import {getValidatedPort} from 'get-port';
import pDefer from 'p-defer';

const app = express();

function listen(port) {
	const {promise, resolve, reject} = pDefer();

	app
		.listen(port, () => {
			app.off('error', reject);
			resolve();
		})
		.on('error', reject);

	return promise;
}

await getValidatedPort(listen);

What should the getValidatedPort function return? If we return the port that is used, we can't access the return value of the validation function and vice versa.

How should we check if the validator function approves an option? In the example, we check for a resolved or rejected promise but we could instead be checking for a boolean value.

v4 to v5 Update Functionality Differences

I may need some guidance as to how to go about nailing down the cause. I'm using getPort in an ava test environment in conjunction with puppeteer and webpack. When using [email protected] everything works as expected. After updating to v5, I get multiple test files attempting to use the same port. My only shot-in-the-dark is that it's somehow related to the changes in v5 to the available port code.

Fwiw, my calls to getPort are relatively simple: getPort({ port: 55555 });

Get the port that is not available

  • Check 4723 in use:

lsof -n -i4TCP:4723

  • Get free port by get-port:
    After 1 minute, i run below code.
const getPort = require('get-port');

(async () => {
  console.log('port 1 -> ', await getPort({ port: 4723 }));

  setTimeout(async () => {
    console.log('port 2 -> ', await getPort({ port: 4723 }));
  }, 2000);
})();

port 1 -> 4723
port 2 -> 50129

My PC is using 4723 port, but get-port still gives me 4723 port.

Screen Shot 2020-03-03 at 1 41 36

PS: I've tried some other library like portfinder and it works as expected.

Default port not catching errors

I am using the default port feature but it does not seem to be catching the error on node 8.9 if the default port is taken. A listen EADDRINUSE error propagates.

Add `exclude` option

See the feedback and initial work in #53 (If you want to work on this, please do a better job than that PR).

document that the port may not be immediately available for (re-)use

since getPort reserves a port and releases it to find an unused port number - trying to use that port number immediately afterwards may not work as *nix machines, which have a re-use timeout for the port to be available again.

This issue is for adding some documentation describing this behavior (if appropriate).

Related post:
https://unix.stackexchange.com/questions/17218/how-long-is-a-tcp-local-socket-address-that-has-been-bound-unavailable-after-clo

Is it possible to fix race condition?

I use this library in my jest tests. Jest runs in parallel ~ 20 test files which use it. For such a use case the chance of race condition is not tiny, I think in my case it's 30%.

Is it possible to fix race condition?

conside provide a synchronous mode options ?

Sometime It would be more convenient if the getPort supports synchronous mode.
For example, when I get the get the test config:

const _ = require('lodash');
const getPort = require('get-port');
const devConfig = require('./development.config');

exports.server = {
    port: getPort({ sync: true }),
};

exports.security = {
    jwtSecret: 'test_jwt_secret',
    passwordHashSaltRounds: 15,
};

exports.db = {
    dbName: 'coo-test',
};

module.exports = _.merge(devConfig, exports);

Requested port is not assigned after 5.0.0 update, even though its available

Hello,

I have an issue. The code is:

./index.js

const getPort = require('get-port');
const {spawn} = require('child_process');
const processExists = require('process-exists');
const delay = require('delay')
const fkill = require('fkill');

async function test() {
  const port = await getPort();
  console.log(port);
  const {pid} = spawn('node', ['fixture.js', port]);
  console.log(`Process exists with PID: ${pid}: ${await processExists(pid)}`);
  await fkill(pid);
  await delay(100);
  console.log(`Process exists with PID: ${pid}: ${await processExists(pid)}`);
	if(!await processExists(pid)) {
    const samePort = await getPort({port});
    console.log(samePort);
  } else {
    console.log('Process not killed');
  }
}

test();

./fixture.js

'use strict';
const http = require('http');

const server = http.createServer((request, response) => {
	response.end();
});

server.listen(process.argv.slice(2)[0]);

With version 4.2.0 the output is as expected

60328
Process exists with PID: 15767: true
Process exists with PID: 15767: false
60328

With ^5.0.0, however, the second time I'm requesting the port, it comes out 1 more than before:

60343
Process exists with PID: 15945: true
Process exists with PID: 15945: false
60344

Has anyone here encountered this issue or knows any way to solve it?

2.x breaking change could have been avoided

Given that get-port now returns a Promise, code that expects it to accept a callback will obviously not work.

I'd encourage you to use something like bluebird's asCallback(). this will make 1.x code still work against 2.x.

function getPort(callback) {
  return new Promise(resolve, reject) {
    // guts
  })
    .asCallback(callback);
});

not a huge issue, but this can cause confusion, because users who used to promisify get-port themselves will end up with a non-working function.

Error: require() of ES Module not supported

I tried using this module in an electron app, both in main and preload processes/scripts.

error:

Uncaught (in promise) Error: require() of ES Module C:\Users..\node_modules\get-port\index.js from C:\Users...\client\dist\preload\index.cjs not supported.
Instead change the require of index.js in C:\Users.....\client\dist\preload\index.cjs to a dynamic import() which is available in all CommonJS modules.
at __node_internal_captureLargerStackTrace (VM12 errors:464:5)
at new NodeError (VM12 errors:371:5)
at Object.Module._extensions..js (VM94 loader:1144:19)
at Module.load (VM94 loader:988:32)
at Module._load (VM94 loader:829:12)
at Function.c._load (VM110 asar_bundle:5:13331)
at Function.o._load (VM113 renderer_init:33:356)
at Module.require (VM94 loader:1012:19)
at require (VM93 helpers:102:18)
at VM115 C:\Users.....client\dist\preload\index.cjs:71:19

app template: git clone https://github.com/ch99q/vite-solid-electron.git

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.