Node.js中写入.json文件时WebSocket断开连接问题排查与解决
问题描述
在Node.js环境中使用ws库搭建WebSocket服务器,收到message事件时通过fs.writeFile将数据写入mydata.json文件,出现以下异常:
- 每次写入
.json文件后,WebSocket服务器会断开连接,但数据已成功写入 - 将文件扩展名改为
.log等其他格式时,无此问题 - 额外测试:本地运行两个独立Node.js服务(一个HTTP服务写
.json文件,一个仅处理WebSocket),当HTTP服务写入.json文件时,WebSocket连接仍会断开
相关代码如下:
package.json
{ "dependencies": { "cors": "^2.8.5", "express": "^4.18.2", "ws": "^8.13.0" }, "scripts": { "dev": "nodemon src/server.js" } }
server.js
const fs = require("fs"); const WebSocket = require("ws"); const wss = new WebSocket.Server({ port: 8080 }); wss.on("connection", (ws) => { console.log("Client connected."); ws.on("message", async (message) => { try { const jsonData = JSON.parse(message); await writeToJSONFile(jsonData); console.log("Data written to file successfully."); } catch (error) { console.error("Error handling JSON data:", error); } }); ws.on("close", () => { console.log("Client disconnected."); }); }); async function writeToJSONFile(data) { return new Promise((resolve, reject) => { fs.writeFile("mydata.json", JSON.stringify(data), (err) => { if (err) { reject(err); } else { resolve(); } }); }); }
问题成因
根本原因是nodemon的文件监听机制:
- 你通过
npm run dev使用nodemon启动服务,nodemon默认会监听项目目录下包括.json在内的常见代码/配置文件的变化 - 当
mydata.json被写入修改时,nodemon会判定为“文件变更”,自动重启Node.js进程 - 进程重启会导致WebSocket服务器被关闭并重建,所有已建立的客户端连接自然断开
- 写入
.log等文件时,nodemon默认不监听这类后缀,因此不会触发重启
即使是两个独立服务,只要WebSocket服务是用nodemon启动且监听范围包含mydata.json,当该文件被修改时,nodemon仍会重启WebSocket服务,导致连接断开。
解决方法
方法1:配置nodemon忽略目标JSON文件
在项目根目录创建nodemon.json配置文件,添加忽略规则:
{ "ignore": ["mydata.json"] }
或者直接在package.json的scripts中添加忽略参数:
{ "scripts": { "dev": "nodemon --ignore mydata.json src/server.js" } }
方法2:将JSON文件移至nodemon不监听的目录
新建一个与源码目录(如src)平级的data目录,修改写入路径:
async function writeToJSONFile(data) { return new Promise((resolve, reject) => { fs.writeFile("./data/mydata.json", JSON.stringify(data), (err) => { if (err) { reject(err); } else { resolve(); } }); }); }
若需更稳妥,可在nodemon配置中明确忽略data目录:
{ "ignore": ["data/"] }
方法3:直接用node命令启动服务(仅临时测试用)
如果不需要nodemon的热重载功能,可直接用原生node命令启动:
node src/server.js
内容的提问来源于stack exchange,提问作者Jie.Zhang
相关产品推荐
相关产品推荐

