get-port: 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

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 24 (13 by maintainers)

Most upvoted comments

but then results will be kinda incorrect, as there will be free port we don’t use.

Yes, but I would argue it’s better with a false-negative than a false-positive. This is just a simple tool to find a free port. It doesn’t really matter if it’s sometimes not actually taken. get-port used to just work and now it doesn’t and I want to get back to that.

Educating people(who already try to write network software ffs) about what the network is and how it works seems like better idea.

That rarely works in practice. It’s IMHO better to adjust to the expected behavior and clearly document everything.

(async () => {
	console.log(await getPort({host:'0.0.0.0',port: [3000,3001]}));
})();

it’is solved

@stroncium What @Carrie999 posted does solve the issue. Can we either note it in the README or fold in the check that @JeffyLo94 added to the internal logic? This way, it is more automatic for folks who are unaware. Otherwise, the README can elaborate on the issue a little more so folks are aware they may need a host specified. I’m happy to contrib either, just looking to you guys to see what is preferred.

@JeffyLo94 You can just pass host option(‘::’ or ‘0.0.0.0’ or any other address) to get-port.

I found this issue from a search engine and it helped me. I agree that this is an issue with the networking layer, but we made assumptions that turned out to bite us. To be specific, in our case, it wasn’t IPv6/IPv4 differences, but instead localhost/127.0.0.1 differences.

So for example, we originally wanted to make requests against: 127.0.0.1:4000 and asked for a port like:

		return {
			port: await getPort({
				port: 4000,
			})
		};

But in doing so, we encountered:

  1. If something else is already listening on localhost:4000 everything (ie our requests to 127.0.0.1:4000) works fine
  2. If something else is already listening on 127.0.0.1:4000, the above code doesn’t error, but it also doesn’t indicate that the port is taken and in so doing, doesn’t give a randomized port for us to use

Updating the above to include the specific host that we would be querying against fixed things:

		return {
			port: await getPort({
                                   host: '127.0.0.1',
				port: 4000,
			})
		};

Hope that helps others!

@stroncium I’ve been thinking about this. Maybe we should just check both :: and 0.0.0.0 by default if host option is not specified? That way it just works no matter what.

I encountered this issue as well. I can confirm it is an ipv6 vs ipv4 issue.

Can this be a possible enhancement: add the option to specify ipv4 or ipv6 when checking the ports. Perhaps add it to your options?

As a temporary work around, if anyone else has issues with this, feel free to use this function as a check (note: this lacks the range features):

const net = require('net');
  getPort (startingPort = 1024, useIpv6 = false) {
    let ipVersion;
    ipVersion = useIpv6 ? '::' : '0.0.0.0';
    const server = net.createServer();
    return new Promise((resolve, reject) => server
    .on('error', error => error.code === 'EADDRINUSE' ? server.listen(++startingPort) : reject(error))
    .on('listening', () => server.close(() => resolve(startingPort)))
    .listen(startingPort, ipVersion))
  }

@labsvisual Can you please provide me with additional info then? I don’t have macos anywhere within reach.

try to actually start a server from nodejs on this port(while your docker container is running) and report if it works and if not then what error it gives