Javascript FS writeFile(同步)导致ws.broadcast无法工作

Javascript FS writeFile(同步)导致ws.broadcast无法工作,javascript,node.js,websocket,fs,Javascript,Node.js,Websocket,Fs,我试图通过在NodeJS中编写一个简单的聊天应用程序来学习WebSocketAPI。我需要将消息保存在一个名为messages.json的文件中,该文件如下所示: [ [ “用户名”, “消息” ], [ “用户名”, “消息” ], ... ] 我已经完成了它的客户端部分。HTML和Javascript文件如下所示: 东西 发送 var user=prompt('Username')。trim() while(user.split(“”).length>1 | | user.trim(

我试图通过在NodeJS中编写一个简单的聊天应用程序来学习
WebSocket
API。我需要将消息保存在一个名为
messages.json
的文件中,该文件如下所示:

[
[
“用户名”,
“消息”
],
[
“用户名”,
“消息”
],
...
]
我已经完成了它的客户端部分。HTML和Javascript文件如下所示:


东西
发送

var user=prompt('Username')。trim()
while(user.split(“”).length>1 | | user.trim()=“”){
user=prompt('Username?')。trim()
}
var ws=newwebsocket(“ws://localhost:8080”);
ws.onopen=函数(事件){
log('Connection successfully opened!');
};
ws.onerror=函数(err){
log('err:',err);
}
ws.onmessage=函数(事件){
var div=document.createElement('div')
div.classList.add('chatMsg')
div.innerText=event.data.split(/(?=[^]+$)/)[1]+':'+事件.data.split(/(?=[^]+$)/)[0]
document.body.appendChild(div)
};
我使用正则表达式分割最后一个空格字符处的数据,因为我发现我无法将数组或对象从客户端发送到服务器,反之亦然,并且用户名不能包含任何空格,尽管我可能意外地将事情过度复杂化了

然后,必须编写服务器端NodeJS代码。当我想永久保存邮件时,我已经完成了:

const express=require('express');
const bodyParser=require('body-parser');
常量app=express();
use(bodyParser.json());
use(bodyParser.urlencoded({extended:true}));
应用程序使用(express.static('public'));
应用程序获取(“/”,(请求,请求)=>{
res.sendFile('public/index.html');
});
app.listen(8000,()=>console.log('server started');
const WebSocketServer=require('ws')。服务器
const wss=新的WebSocketServer({port:8080});
wss.on('连接',((ws)=>{
ws.on('消息',(消息)=>{
广播(信息);
});
ws.on('end',()=>{
log('连接已结束…');
});
}));
wss.broadcast=功能广播(msg){
forEach(每个函数(客户端){
client.send(msg);
});
};
到目前为止,我能够从一个浏览器选项卡发送消息,而另一个选项卡能够正确接收消息并发送另一条消息,依此类推。我认为永久保存消息的最好方法是JSON文件,因此我创建了一个名为
messages.JSON
的文件,如上所述

在程序开始时,我通过包含
var messages=require('../messages.json')
require
d模块
fs
来读取文件,以写入
messages.json

const fs=require('fs');
const messages=require('./messages.json');
然后我将
ws.on('message',(message)=>{…
更改为如下所示:

ws.on('message',(message)=>{
messages.push(message.split(/(?=[^]+$)/)
fs.writeFile('./messages.json',json.stringify(messages),()=>{})
广播(信息);
});
然后,我在浏览器的
文件中打开了两个选项卡://…/public/index.html
。我从第一个选项卡发送了一条消息。然后切换到第二个选项卡并尝试发送消息。我在输入中键入了一些内容,然后按下“发送”按钮,输入中的文本消失了,但没有发生其他任何事情。然后我切换回第一个选项卡并尝试了相同的操作,但其行为与第二个选项卡相同。我切换回VSCode窗口并检查了终端,但没有出现错误。我打开了
messages.json
和sa数组中只有一条消息。文件如下所示:

[
[
“用户”,
“测试”
]
]
我很困惑,因为我发送了三条消息,但文件中只记录了一条。我将
messages.json
重置为
[]
,并使用
fs.readFileSync
而不是
fs.readFile
。没有任何更改,然后,出于调试目的,我更改了
fs.writeFile('./messages.json',json.stringify)行(messages),()=>{}
console.log('test')
。我关闭了两个选项卡并再次打开它们。然后,我从第一个选项卡发送了一条消息,从第二个选项卡发送了一条消息,从第一个选项卡发送了另一条消息。一切正常,两个选项卡都显示了消息。终端显示了输出:

测试
测试
测试
它按预期工作。为什么它不能与
fs.readFile
fs.readFileSync
一起工作

要运行并重新加载服务器,我将使用名为
live
的NPM脚本和
nodemon

“脚本”:{
“live”:“nodemon index.js”
},
要启动服务器,我只需在终端中运行
nodemon index.js

我的目录结构:

node\u模块
公众的
|--index.html
|--script.js
index.js
messages.json
package.json

问题是我使用
require()
读取JSON文件,因为这是一种更简单、更短的方法。我可以通过使用
JSON.parse(fs.readFileSync('./messages.JSON',()=>{}).toString()
而不是
require('./messages.JSON')
来修复它

const express=require('express'))
const bodyParser=require('body-parser')
常量fs=require('fs')
const app=express()
var messages=JSON.parse(fs.readFileSync('./messages.JSON',()=>{}.toString())
app.use(bodyParser.json())
use(bodyParser.urlencoded({extended:true}))
应用程序使用(express.static('public'))
应用程序获取(“/”,(请求,请求)=>{
res.sendFile('public/index.html')
})
app.listen(8000,()=>{})
const WebSocketServer=require('ws')。服务器
const wss=新的WebSocketServer({port:8080})
wss.on('连接',((ws)=>