错误:监听EADDRINUSE:地址已在使用::: 3001 [Nodemon,Node.js]

时间:2020-06-22 08:05:22

标签: javascript node.js nodemon

多年来我一直在使用Windows 10笔记本电脑,现在我换成了MacBook。我从Github中提取了一些代码(使用与服务器完全相同的代码),Nodemon不想在我点击save时自动重启服务器。发生了什么事?

index.js:

const express = require("express");
const path = require("path");
const cors = require("cors");
const bodyParser = require("body-parser");
const http = require("http");

const app = express();
const server = http.createServer(app);

app.use(express.json({ extended: false, limit: "5mb" }));
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

if (process.env.NODE_ENV === "production") {
    app.use(express.static("client/build"));
    app.get("*", (req, res) =>
        res.sendFile(path.resolve(__dirname, "client", "build", "index.html"))
    );
}

const PORT = process.env.PORT || 3001;

server.listen(PORT, () => console.log(`Server started on port ${PORT}.`));

我进行了一些更改,然后单击“保存”,然后出现此错误:

events.js:292
[0]       throw er; // Unhandled 'error' event
[0]       ^
[0] 
[0] Error: listen EADDRINUSE: address already in use :::3001

Package.json:

"scripts": {
        "start": "node index.js",
        "server": "nodemon index.js",
        "client": "npm start --prefix client",
        "dev": "concurrently \"npm run server\" \"npm run client\""
},

我想要的是当我点击保存时,它会保存所有内容,然后在同一端口上重新启动服务器。一切都是自动的。我不想每次保存时都手动终止服务器。此版本适用于Windows 10,现在不适用于我的MacBook ...

1 个答案:

答案 0 :(得分:1)

当Nodemon检测到任何受监视文件中的更改时,它将向加载的应用程序发送SIGUSR2信号,然后在内存中重新生成(“重新加载”)该应用程序的新实例。如果您不处理该SIGUSR2信号,则您的应用程序的旧副本将仍然有效,并在端口3001(或其他端口)上侦听传入的请求。

因此新实例正在启动。它将监听相同的编程端口,即3001。但是由于旧副本尚未失效(仍在运行),因此仍使用该端口,这将导致:

错误:监听EADDRINUSE:地址已在使用中

这就是问题的根源。

解决方案是监听SIGUSR2信号,并在发生该事件时以编程方式正常关闭应用程序。将以下行添加到代码中的某处,越早越好:

process.once("SIGUSR2", () => server.close(err => process.kill(process.pid, "SIGUSR2")));

现在,您的应用程序在看到该信号时将自行终止。上面的代码可能无法100%正常工作,但是遵循此模式,人们可以侦听许多其他POSIX信号并进行相应处理,例如SIGINT,SIGABRT,SIGHUP,SIGTERM等。Read more

了解有关Nodemon的更多信息,并在Nodemon page上优雅地重新加载脚本。