每次实例化我的类的新实例时,我的项目都需要设置一个新端口。
在Node.js中如何找到一个可在我的新套接字服务器中设置的免费TCP端口?或者检查我的指定端口是否已经使用过。
答案 0 :(得分:42)
您可以通过为端口指定0
来绑定到操作系统分配的随机空闲端口。这样您就不会受到竞争条件的影响(例如,在您有机会绑定它之前检查一个开放端口和一些绑定到它的进程)。
然后,您可以通过调用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);
});
答案 1 :(得分:3)
要查找已打开的TCP端口,您可以使用模块portastic
您可以找到这样的端口:
port = require('portastic');
options = {
min : 8000,
max : 8005
}
port.find(options, function(err, data){
if(err)
throw err;
console.log(data);
});
答案 2 :(得分:2)
对于Express应用:
const app = require('express')();
const server = app.listen(0, () => {
console.log('Listening on port:', server.address().port);
});
答案 3 :(得分:0)
使用portfinder或get-port模块(portastic太旧了)。他们俩都做得不错。
答案 4 :(得分:0)
对于那些尝试“同步”执行此操作的用户,下游代码取决于操作系统选择的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);
}
})
答案 5 :(得分:0)
在构建在本地运行的应用程序时,我在很多场合都使用了公认的答案-感谢@mscdex。但是,最近我有一个用例,如果可能的话,最好坚持使用一个给定的端口,但是如果使用该端口,则仍然要回退到另一个端口。
这样做的原因是我想使用localStorage保存应用程序首选项,该存储仅限于同一站点,并具有相同的端口以确保安全。因此,我希望在可能的情况下始终使用端口3000,但如有需要,请回退到3001或3002等,直到可用为止。如果使用的端口不是3000,那么我将退回到存储在用户硬盘上的应用程序首选项的副本。
我使用以下模式进行此操作:
ArrayDeque
const http = require('http');
const server = http.createServer(function(req,res){ ... })
const config = {
port: 3000,
launched: false,
};
serverListen(server, config.port);
function serverListen(server, port){
server.on('error', e => {
console.log(`port ${config.port} is taken`)
config.port +=1;
server.close();
serverListen(server, config.port);
}).listen(port, function() {
if (config.launched){
return;
}
console.log('Listening on port ' + server.address().port);
launchBrowser();
config.launched = true;
});
}
只是一个将浏览器启动到launchBrowser()
该应用程序是一个简单的本地服务器+浏览器应用程序。浏览器是GUI,服务器则在用户的硬盘驱动器上进行文件等的修改。
答案 6 :(得分:0)
端口查找器库:
https://github.com/http-party/node-portfinder
我建议您使用 portfinder
库,它在一周内的下载量超过 1000 万次。
默认情况下,portfinder
库将从 8000 开始搜索并扫描,直到达到最大端口号 (65535)。
const portfinder = require('portfinder');
portfinder.getPort((err, port) => {
//
// `port` is guaranteed to be a free port
// in this scope.
//
});