gpt4 book ai didi

javascript - readFile 未在 while 循环内运行

转载 作者:行者123 更新时间:2023-12-03 01:05:52 24 4
gpt4 key购买 nike

每次使用 Express 更新文本文件时,我都尝试通过套接字连接发送文本文件的内容:

console.log('Server running!');

var express = require('express');
var app = express();
var server = app.listen(3000);
var fs = require("fs");
var x = 0;

app.use(express.static('public'));

var socket = require('socket.io');
var io = socket(server);

io.sockets.on('connection', newConnection);

function newConnection(socket) {
console.log("New connection: " + socket.id);
while (true) {
fs.readFile('song.txt', function(err, data) {
if (err) throw err;
console.log(data);
if (data != x) {
var songdata = data;
console.log(songdata);
io.sockets.emit('update', songdata);
x = data;
} else {
console.log("Song is not different:)");
}
})
}
}

如果没有 while 循环,一切都会正常工作,我会在单独的客户端中收到内容。但是,现在什么也没有发生,没有数据的控制台日志。这表明readFile突然不再运行,为什么?

谢谢:)

最佳答案

首先,一些基础知识。 node.js 将 Javascript 作为单线程运行,因此这是一个单线程服务器。它一次只能用你的 Javascript 做一件事。但是,如果你仔细地对其进行编程,它可以很好地扩展并做很多事情。

其次,您几乎不想在服务器端 Javascript 中执行 while (true) 操作。这将永远运行,并且永远不会让任何其他东西在您的服务器上运行。没有别的了。

第三,每次新客户端连接时,您都尝试创建该无限循环的新版本。这不是一个正确的设计(即使没有无限循环)。您只需要一个代码实例来检查文件,而不是 N 个。

现在,如果您真正想要做的是“轮询”song.txt 中的更改并在更改时通知客户端,那么您需要选择一个合理的时间增量检查文件并使用计时器。这将经常检查该文件,并让您的服务器在其余时间正常运行。

这是一个使用 setInterval() 进行轮询的简单版本:

console.log('Server code started!');

const express = require('express');
const app = express();
const server = app.listen(3000);
const fs = require("fs");
let lastSongData = 0;

app.use(express.static('public'));

const io = require('socket.io')(server);

// get initial songData for future use
// there will not be any connected clients yet so we don't need to broadcast it
try {
lastSongData = fs.readFileSync('song.txt');
} catch(e) {
console.log(e, "\nDidn't find song.txt on server initialization");
}

// here, we create a polling loop that notifies all connected clients
// any time the song has changed
const pollInterval = 60*1000; // 60 seconds, ideally it should be longer than this
const pollTimer = setInterval(() => {
fs.readFile('song.txt', (err, songData) => {
if (!err && songData !== lastSongData) {
// notify all connect clients
console.log("found changed songData");
io.emit('update', songData);
lastSongData = songData;
}
});
}, pollInterval);

io.sockets.on('connection', socket => {
console.log("New connection: " + socket.id);
});

如果您的 songData 是二进制的,那么您将必须更改将数据发送到客户端的方式以及将数据与先前数据进行比较的方式,以便您发送和接收二进制数据,而不是字符串数据,因此您正在比较缓冲区,而不是字符串。

以下是有关使用 socket.io 发送二进制数据的一些引用:

How to send binary data with socket.io?

How to send binary data from a Node.js socket.io server to a browser client?

<小时/>

检测文件更改的更有效方法是使用 fs.watch() ,它应该通知您文件的更改,尽管您必须在任何平台上彻底测试它正在运行以确保它按照您想要的方式工作。该功能有编号platform caveats (它在所有平台上的工作方式并不相同),因此您必须在您的平台上对其进行彻底测试,看看是否可以将其用于您想要的用途。

console.log('Server code started!');

const express = require('express');
const app = express();
const server = app.listen(3000);
const fs = require("fs");
let lastSongData = 0;

app.use(express.static('public'));

const io = require('socket.io')(server);

// get initial songData for future use
// there will not be any connected clients yet so we don't need to broadcast it
try {
lastSongData = fs.readFileSync('song.txt');
} catch(e) {
console.log(e, "\nDidn't find song.txt on server initialization");
}

// ask node.js to tell us when song.txt is modified
fs.watch('song.txt', (eventType, filename) => {
// check the file for all eventTypes
fs.readFile('song.txt', (err, songData) => {
if (!err && songData !== lastSongData) {
// notify all connect clients
console.log("found changed songData");
lastSongData = songData;
io.emit('update', songData);
}
});
});

io.sockets.on('connection', socket => {
console.log("New connection: " + socket.id);
});
<小时/>

从您的原始代码中不清楚您是否需要将 songData 发送到每个新连接(无论最近是否已更改)。

如果是这样,您只需将连接事件处理程序更改为:

io.sockets.on('connection', socket => {
console.log("New connection: " + socket.id);
// send most recent songData to each newly connected client
if (lastSongData) {
socket.emit('update', lastSongData);
}
});

关于javascript - readFile 未在 while 循环内运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52414402/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com