-
-
Save timoxley/1689041 to your computer and use it in GitHub Desktop.
var isPortTaken = function(port, fn) { | |
var net = require('net') | |
var tester = net.createServer() | |
.once('error', function (err) { | |
if (err.code != 'EADDRINUSE') return fn(err) | |
fn(null, true) | |
}) | |
.once('listening', function() { | |
tester.once('close', function() { fn(null, false) }) | |
.close() | |
}) | |
.listen(port) | |
} |
I'm actually using this to do a check that my app will eventually start listening on a particular port in a test case. It is a crappy check though, since any app could be using that port and the assertion would pass.
thanks for the code!
Horrible code style :-)
Sweet, didn't want to install yet another module just to do a simple port check. Thanks for sharing this snippet!
Ty for this!
I actually need more this than portfinder since I need to listen when process b is not using the port x so process a can be closed.
I will test if works, tho.
Thanks
Whoever wrote portfinder does not know about port 0
For my purposes, I needed to know whether a process was listening on a port (indicating that it was hung & needed to be killed), not just whether the port was available. These aren't exactly the same thing, since newer versions of Node try IPv6 and then fall back to IPv4, so it returns false
even though a process is listening, since a second process can still listen on the other IP version. The following code returns true
if the port is taken on either IPv4 or IPv6:
function isPortTaken(port, fn) {
var success_ix = 0;
var net = require('net')
var test_ipv4 = net.createServer()
.once('error', function (err) {
if (err.code != 'EADDRINUSE') return fn(err)
fn(null, true)
})
.once('listening', function() {
test_ipv4.once('close', function() { success_ix++; if (success_ix == 2) fn(null, false) })
.close()
})
.listen(port, '0.0.0.0');
var test_ipv6 = net.createServer()
.once('error', function (err) {
if (err.code != 'EADDRINUSE') return fn(err)
fn(null, true)
})
.once('listening', function() {
test_ipv6.once('close', function() { success_ix++; if (success_ix == 2) fn(null, false) })
.close()
})
.listen(port, '::');
}
Note that this attempts binding to all interfaces (*
), if you want to check specifically against localhost
, use ::1
instead of ::
and use 127.0.0.1
instead of 0.0.0.0
. Also note that the callback will be called twice if the port is taken on both IPv4 and IPv6.
This is a version of the original using a promise :)
const isPortTaken = (port) => new Promise<boolean>((resolve, reject) => {
const tester = Net.createServer()
.once('error', err => (err.code == 'EADDRINUSE' ? resolve(false) : reject(err)))
.once('listening', () => tester.once('close', () => resolve(true)).close())
.listen(port)
})
you've implemented isPortAvailable
or isPortNotTaken()
in my opinion, "isPortTaken" should not return false when the port is available
i think its best to make it as a node global module to be able to call it in any project directories... anyways nice style ;0
I published a simple npm package, inspired by this code: is Port Available
This is simple and easy to use. No need of installing extra package. I just can copy & paste it in my code and it just works. Thank you so much for making it simple.
This is a version of the original using a promise :)
const isPortTaken = (port) => new Promise<boolean>((resolve, reject) => { const tester = Net.createServer()
//resolve true not false
.once('error', err => (err.code == 'EADDRINUSE' ? resolve(true) : reject(err)))
// resolve false not true
.once('listening', () => tester.once('close', () => resolve(false)).close()) .listen(port)
})
I like to use this instead! :-)
Thnx man 😉
I like to use this instead! :-)
Thanks. This is a very simple and easy to use package.
a promise implement
import { createServer } from "net";
const isPortTaken = (port: number, type: 'IPv4' | 'IPv6' = 'IPv4') => {
let hasError = 0;
return new Promise((res) => {
const server = createServer()
.once('error', err => { if (err) { res(false) } })
.once('listening', () => {
server
.once('close', () => {
hasError++;
if (hasError > 1) {
res(false)
} else {
res(true)
}
})
.close()
})
.listen(port, type === 'IPv4' ? '0.0.0.0' : '::')
})
};
Test without producing an error
on mac and most unix/linux
const { spawnSync } = require('child_process')
function checkPort(port) {
const output = spawnSync(
`lsof -i tcp:${port} | awk '{print $2}' |grep --invert PID`,
{ shell: true }
)
if (output.error) {
console.error(output.error)
return
}
const pid = Buffer.from(output.stdout.buffer).toString().split('\n')[0]
console.log({ pid })
return pid
}
const pid = checkPort(443))
if (pid) {
console.log(`server is running, process id ${pid}`)
}
const pid = checkPort(443))
@tysonrm – nice technique! FYI, there's an extra )
when making the checkPort()
example.
I like to use this instead! :-)
https://github.com/indexzero/node-portfinder