You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 08:13:24