Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
get a new/clean port with node.js
var portrange = 45032
function getPort (cb) {
var port = portrange
portrange += 1
var server = net.createServer()
server.listen(port, function (err) {
server.once('close', function () {
cb(port)
})
server.close()
})
server.on('error', function (err) {
getPort(cb)
})
}
@felipenmoura
Copy link

What about a promisified version

function getAvailablePort (startingAt) {

    function getNextAvailablePort (currentPort, cb) {
        const server = net.createServer()
        server.listen(currentPort, _ => {
            server.once('close', _ => {
                cb(currentPort)
            })
            server.close()
        })
        server.on('error', _ => {
            getNextAvailablePort(++currentPort, cb)
        })
    }

    return new Promise(resolve => {
        getNextAvailablePort(startingAt, resolve)
    })
}

Can be used as promise:

getAvailablePort(3030).then(port => { console.log(`${port} is available`)})

Or with async/await:

async function () {
    // ...
    const port = await getAvailablePort(3000)
    // ...
}

@LucasBadico
Copy link

About this net.createServer() right below getNextAvailablePort definition, you get from where?

@nyn0x
Copy link

nyn0x commented Jun 19, 2018

const net = require('net');

@leviwheatcroft
Copy link

leviwheatcroft commented Sep 21, 2018

see you and raise you @felipenmoura:

import { createServer } from 'net'
function getPort(port = 3000) {
  return new Promise((resolve, reject) => {
    const server = createServer()
    server.on('error', (err) => {
      if (err.code !== 'EADDRINUSE') return reject(err)
      server.listen(++port)
    })
    server.on('listening', () => server.close(() => resolve(port)))
    server.listen(port)
  })
}

usage: const port = await getPort()

@ronen
Copy link

ronen commented Mar 21, 2019

see you and raise you @leviwheatcroft :)

import { createServer } from 'net'
function getPort() {
  return new Promise((resolve, reject) => {
    const server = net.createServer()
    server.on('error', reject)
    server.on('listening', () => (port => server.close(() => resolve(port)))(server.address().port))
    server.listen(0)
  })
}

@jonathantneal
Copy link

I like this game, @ronen: ^_^

import { createServer } from 'net'
function getPort (port = 80) {
  const server = createServer()
  return new Promise((resolve, reject) => server
  .on('error', error => error.code === 'EADDRINUSE' ? server.listen(++port) : reject(error))
  .on('listening', () => server.close(() => resolve(port)))
  .listen(port))
}

Usage

const port = await getPort()

@matthewadams
Copy link

matthewadams commented Jan 3, 2020

@ronen & @jonathantneal, reraise:

import { createServer } from 'net'

function getPort (port = 80, maxPort = 65535) {
  if ((maxPort = parseInt(maxPort)) < (port = parseInt(port))) {
    return Promise.reject((() => {
      const e = new Error('EPORTSPEC')
      e.code = e.message
      return e
    })())
  }
  const server = createServer()
  return new Promise((resolve, reject) => server
    .once('error', error => error.code !== 'EADDRINUSE' || ++port > maxPort ? reject(error) : server.listen(port))
    .once('listening', () => server.close(() => resolve(port)))
    .listen(port)
  )
}

NB: edited to remove port range checks since server.listen has that check; only need to check that maxPort > port.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment