如何接收多个WebSocket JSON对象并分别使用、避免存储覆盖?
问题原因
你的代码每次收到WebSocket消息时,都通过fs.createWriteStream('output.json')创建写入流,而该方法默认使用覆盖模式(flags: 'w'),会清空文件后写入当前的JSON对象,所以最终文件里只会保留最后一条数据。
解决方案
根据你的使用场景,提供三种可行的实现方式:
方式1:内存维护数组,写入完整JSON数组(适合数据量不大、需要标准JSON格式的场景)
全局声明一个数组存储所有学生数据,每次收到消息就将解析后的对象加入数组,再将整个数组写入文件。
const WebSocket = require('ws'); const fs = require('fs'); // 模块放在顶部加载,避免重复初始化 const serverAddress = '*SERVER NAME*'; const ws = new WebSocket(serverAddress, { headers: { "user-agent": "Mozilla" } }); // 全局数组存储所有学生数据 let studentData = []; ws.on('open', function () { console.log('已连接到WebSocket服务器'); }); ws.on('message', function (msg) { console.log(msg.toString()); const studentObj = JSON.parse(msg); // 将新数据加入数组 studentData.push(studentObj); // 将完整数组转为JSON字符串写入文件 fs.writeFile('output.json', JSON.stringify(studentData, null, 2), (err) => { if (err) console.error('写入文件失败:', err); }); });
方式2:追加写入JSON Lines格式(适合大数据量、低内存占用的场景)
每行存储一个独立的JSON对象,文件后缀常用.jsonl,读取时按行解析即可,无需维护内存数组。
const WebSocket = require('ws'); const fs = require('fs'); const serverAddress = '*SERVER NAME*'; const ws = new WebSocket(serverAddress, { headers: { "user-agent": "Mozilla" } }); ws.on('open', function () { console.log('已连接到WebSocket服务器'); }); ws.on('message', function (msg) { console.log(msg.toString()); // 追加一行JSON字符串,末尾加换行符分隔 fs.appendFile('output.jsonl', msg.toString() + '\n', (err) => { if (err) console.error('追加文件失败:', err); }); });
方式3:增量维护JSON数组(适合需要标准JSON格式、不想每次重写整个文件的场景)
读取现有文件内容,修改数组后再写入,避免每次重写全部数据:
const WebSocket = require('ws'); const fs = require('fs'); const serverAddress = '*SERVER NAME*'; const ws = new WebSocket(serverAddress, { headers: { "user-agent": "Mozilla" } }); const filePath = 'output.json'; // 初始化文件:如果不存在则写入空数组 if (!fs.existsSync(filePath)) { fs.writeFileSync(filePath, '[]'); } ws.on('open', function () { console.log('已连接到WebSocket服务器'); }); ws.on('message', function (msg) { console.log(msg.toString()); const studentObj = JSON.parse(msg); // 读取现有数据并更新 fs.readFile(filePath, 'utf8', (err, data) => { if (err) { console.error('读取文件失败:', err); return; } try { const studentArr = JSON.parse(data); studentArr.push(studentObj); fs.writeFile(filePath, JSON.stringify(studentArr, null, 2), (err) => { if (err) console.error('写入文件失败:', err); }); } catch (parseErr) { console.error('文件格式错误:', parseErr); } }); });
额外优化点
- 不要在
message回调里重复执行fs = require('fs'),模块加载放在文件顶部即可,避免不必要的性能损耗。
内容的提问来源于stack exchange,提问作者user17322569
相关产品推荐
相关产品推荐

