reactjs - 带有 mern 堆栈的 Socket io 使用 100% 的 CPU 功率
问题描述
我从我的主管那里得到了一个任务,要创建一个具有基本套接字 io 功能的程序,但我对此一无所知,所以我学会了它,这对我来说似乎很容易。在我的计算机程序上运行良好,但是在我将程序安装在生产服务器上后,当事件从前端发送到使用 React 编写的套接字 io 时,它使用了 100% 的 CPU。
这是我的套接字服务器。
const mongoose = require("mongoose");
const prevNum = require("./models/prevNums");
const Score = require("./models/scores");
const dotenv = require("dotenv");
const Config = require("./models/configs");
const Graphic = require("./models/graphic");
const Ip = require("./models/ips");
dotenv.config();
const mongoDB = process.env.MONGO_DB;
const io = require("socket.io")(9090, {
cors: {
origin: "*",
methods: ["GET", "POST"],
credentials: true,
},
});
const axios = require("axios");
const appName = "tennis_socket_server";
// function console.log(log, options) {
// if (options) {
// options.forEach(opt => {
// log += JSON.stringify(opt);
// })
// } else {
// log = JSON.stringify(log)
// }
// console.log(log);
// axios.post('http://192.168.2.202:9099/log', { app: appName, log })
// }
mongoose
.connect(mongoDB, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log("Mongoose is connected for socket server!!!");
})
.catch((err) => console.log(err));
function deletePrev(reverse) {
prevNum.find({}).then((data) => {
if (reverse) {
prevNum.deleteOne(data[data.length - 1], (a, b) => {});
} else {
if (data.length >= 50) {
prevNum.deleteOne(data[0], (a, b) => {});
}
}
});
}
function filterState(state) {
return {
player1: state.player1,
player2: state.player2,
wonGames1: state.wonGames1,
wonGames2: state.wonGames2,
lastSet: state.lastSet,
doNotReverse: state.doNotReverse,
reverseInLastSet: state.reverseInLastSet,
names: state.names,
tourID: state.tourID,
};
}
function getSets(callback) {
console.log("getSets");
Score.find({}).then((data) => {
let sets = [];
data.forEach((e) => {
if (
e.checked !== true &&
(e.finished === true ||
(e.finishedGame === true && (e.wonGames1 === 5 || e.wonGames2 === 5)))
) {
sets.push(e);
}
});
io.emit("setSets", sets);
});
}
io.on("connection", (socket) => {
console.log("New device connected to socket server at 9090", [
socket.handshake.address,
]);
// socket.on('disconnect', () => {
// console.log('Device disconnected from socket server at 9090', [socket.handshake.address]);
// Ip.find({ip:socket.handshake.address})
// .then(data => {
// if(data.length > 0){
// Ip.deleteOne(data[0], (msg, err) => {
// console.log("delete", err)
// Ip.find({ })
// .then(data => {
// io.emit('setIps', data);
// })
// })
// }
// })
// })
// Ip.find({})
// .then(data => {
// io.emit('setIps', data);
// })
Score.find({}).then((data) => {
Config.find({}).then((config) => {
if (data[data.length - 1]) {
let datum = new Object(data[data.length - 1]);
datum = { ...datum };
datum = datum._doc;
let conif = {};
if (config.length > 0) {
conif = new Object(config[config.length - 1]);
conif = { ...conif };
conif = conif._doc;
}
io.emit("setScores", { ...datum, ...conif });
} else {
let newScore = new Score({
player1: 0,
player2: 0,
wonGames2: 0,
wonGames1: 0,
});
newScore.save().then(() => {
if (config.length === 0) {
let newConfigs = new Config({
neededSetsToWin: 11,
neededGamesToWin: 5,
block: false,
delay: true,
});
newConfigs.save().then(() => {
io.emit("setScores", {
neededSetsToWin: 11,
neededGamesToWin: 5,
player1: 0,
player2: 0,
wonGames2: 0,
wonGames1: 0,
});
});
} else {
io.emit("setScores", {
player1: 0,
player2: 0,
wonGames2: 0,
wonGames1: 0,
});
}
});
}
});
});
// socket.on('writeMyIP', () => {
// let newIP = new Ip({ip:socket.handshake.address});
// newIP.save()
// .then(() => {
// Ip.find({ })
// .then(data => {
// io.emit('setIps', data);
// })
// })
// })
socket.on("newSet", (scores) => {
console.log("new set");
Score.find({}).then((data) => {
let newPrevDocument = new prevNum({
...filterState(data[data.length - 1]),
});
newPrevDocument.save().then(() => {
deletePrev();
let newDocument = {
wonGames1: scores.wonGames1,
wonGames2: scores.wonGames2,
finished: true,
time: new Date(),
checked: false,
};
Score.updateOne(data[data.length - 1], newDocument, (a, b) => {}).then(
() => {
let oldScoreDocument = new Score({
...scores,
player1: 0,
player2: 0,
finished: false,
time: new Date(),
tourID: data[data.length - 1].tourID,
});
oldScoreDocument.save().then(() => {
io.emit("setScores", {
...scores,
player1: 0,
player2: 0,
tourID: data[data.length - 1].tourID,
});
getSets();
});
}
);
});
});
});
socket.on("finishGame", () => {
console.log("finish game");
Score.find({}).then((data) => {
Score.updateOne(
data[data.length - 1],
{ finishedGame: true, time: new Date() },
(a, b) => {
getSets();
}
);
});
prevNum.remove({}, (a, b) => {});
});
socket.on("newGame", () => {
console.log("newGame");
let newScoreDocument = new Score({
player1: 0,
player2: 0,
wonGames1: 0,
wonGames2: 0,
startTime: new Date(),
});
newScoreDocument.save().then(() => {
io.emit("setScores", {
player1: 0,
player2: 0,
wonGames1: 0,
wonGames2: 0,
gonnaWin: {},
lastSet: false,
doNotReverse: false,
reverseInLastSet: false,
});
Score.find({}).then((data) => {
Score.updateOne(data[data.length - 1], { started: true }, (msg, err) =>
console.log(msg, err)
).then(() => {
let newTourID = data[data.length - 2].tourID;
if (
newTourID[newTourID.length - 2] +
newTourID[newTourID.length - 1] ===
"30"
) {
newTourID = newTourID.slice(0, -3);
let newTour = parseInt(newTourID[newTourID.length - 1], 10) + 1;
if (newTour - 3 > 0) {
newTour -= 3;
let d = new Date(newTourID.slice(0, -2));
d.setDate(d.getDate() + 1);
d = d.toISOString().split("T")[0];
newTourID = [d, newTour].join("-");
} else {
newTourID = newTourID.slice(0, -1);
newTourID += newTour;
}
Graphic.find({ tourID: newTourID }).then((data) => {
if (data.length > 0) {
let newNames = data[0].graphic[0];
let newTourIDWithGame = newTourID + "-1";
io.emit("setScores", {
names: {
player1: newNames[0],
player2: newNames[1],
judge: newNames[2],
},
tourID: newTourIDWithGame,
});
getSets();
} else {
io.emit("setScores", {
names: {
player1: "Игрок 1",
player2: "Игрок 2",
judge: "Судья",
},
tourID: "",
});
getSets();
}
});
} else {
let lastGame = newTourID[newTourID.length - 1];
newTourID = newTourID.slice(0, -1);
if (newTourID[newTourID.length - 1] !== "-") {
lastGame = newTourID[newTourID.length - 1] + lastGame;
newTourID = newTourID.slice(0, -1);
}
newTourID = newTourID.slice(0, -1);
Graphic.find({ tourID: newTourID }).then((data) => {
if (data.length > 0) {
let newNames = data[0].graphic[parseInt(lastGame, 10)];
let newTourIDWithGame =
newTourID + "-" + (parseInt(lastGame, 10) + 1);
io.emit("setScores", {
names: {
player1: newNames[0],
player2: newNames[1],
judge: newNames[2],
},
tourID: newTourIDWithGame,
});
getSets();
} else {
io.emit("setScores", {
names: {
player1: "Игрок 1",
player2: "Игрок 2",
judge: "Судья",
},
tourID: "",
});
getSets();
}
});
}
});
});
});
});
socket.on("undoScores", (changeSet) => {
prevNum.find({}).then((data) => {
Score.find({}).then((scoreData) => {
let scores = data[data.length - 1];
let newScore = filterState(scores);
let prevScore = scoreData[scoreData.length - 1];
console.log("undo");
if (prevScore) {
prevScore = filterState(prevScore);
if (
prevScore.player1 === newScore.player1 &&
prevScore.player2 === newScore.player2 &&
prevScore.wonGames1 === newScore.wonGames1 &&
prevScore.wonGames2 === newScore.wonGames2
) {
Score.deleteOne(scoreData[scoreData.length - 1], (a, b) =>
console.log(a, b)
).then(() => {
Score.updateOne(scoreData[scoreData.length - 2], {
finished: false,
finsihedGame: false,
started: false,
}).then(() => {
io.emit("setScores", newScore);
deletePrev(true);
});
});
} else if (
prevScore.wonGames1 !== newScore.wonGames1 ||
prevScore.wonGames2 !== newScore.wonGames2
) {
if (changeSet) {
Score.deleteOne(scoreData[scoreData.length - 1], (a, b) =>
console.log(a, b)
).then(() => {
Score.updateOne(scoreData[scoreData.length - 2], {
finished: false,
...newScore,
}).then(() => {
io.emit("setScores", { ...newScore, changeSet: false });
deletePrev(true);
getSets();
});
});
} else {
io.emit("setScores", { changeSet: true });
}
} else {
Score.updateOne(scoreData[scoreData.length - 1], newScore).then(
() => {
io.emit("setScores", newScore);
deletePrev(true);
}
);
}
} else {
Score.updateOne(scoreData[scoreData.length - 1], newScore).then(
() => {
io.emit("setScores", newScore);
deletePrev(true);
}
);
}
});
});
});
socket.on("help", () => {
io.emit("help");
});
socket.on("refresh", () => {
io.emit("refresh");
});
socket.on("scoreUpdate", (scores) => {
console.log("scoreUpdate", [scores]);
// console.log(scores);
Score.find({}).then((data) => {
if (data[data.length - 1]) {
if (!data[data.length - 1].finished) {
deletePrev();
let datum = data[data.length - 1];
let newPrevs = {
player1: datum.player1,
player2: datum.player2,
wonGames1: datum.wonGames1,
wonGames2: datum.wonGames2,
doNotReverse: datum.doNotReverse,
lastSet: datum.lastSet,
reverseInLastSet: datum.reverseInLastSet,
names: datum.names,
tourID: datum.tourID,
};
console.log(scores);
let prevNumDocument = new prevNum(newPrevs);
prevNumDocument.save().then(() => {
Score.updateOne(data[data.length - 1], scores).then(() => {
io.emit("setScores", scores);
});
});
}
} else {
let newScoreDocument = new Score({ ...scores, time: new Date() });
newScoreDocument.save().then(() => {
io.emit("setScores", scores);
});
}
});
});
socket.on("setTourID", (info) => {
let tourID = [info.date, info.tour, info.game].join("-");
let tourIDNoGame = [info.date, info.tour].join("-");
Score.find({}).then((scores) => {
Graphic.find({ tourID: tourIDNoGame }).then((data) => {
if (data.length > 0) {
let player1 = data[0].graphic[info.game - 1][0];
let player2 = data[0].graphic[info.game - 1][1];
let judge = data[0].graphic[info.game - 1][2];
Score.updateOne(
scores[scores.length - 1],
{ names: { player1, player2, judge }, tourID },
(msg, err) => {
console.log(msg, err);
io.emit("setScores", {
names: { player1, player2, judge },
tourID,
});
}
);
}
});
});
});
socket.on("warn", (text) => {
io.emit("warn", text);
});
socket.on("getSets", (callback) => getSets(callback));
socket.on("saveSet", (res) => {
let s = res.set;
console.log("saveSet");
Score.find({ _id: s._id }).then((data) => {
Score.updateOne(
data[data.length - 1],
{ ...s, modified: true },
(msg, err) => {
getSets();
console.log(msg, err);
}
);
});
});
});
我从前端发送socket.emit('name', {a small object as argument});
我没有将我的程序设置为生产模式,但我认为它不会发挥重要作用,因为同时连接到我的服务器的设备不超过 10 个。
我想socket io
使用更少的CPU。
解决方案
推荐阅读
- git - Fastlane 错误:无法从自定义 Fastfile 更新我的分发证书:匹配
- html - 预览由 textarea 输入的完整 HTML 页面
- python - 如何使用 BeautifulSoup 获得“id”值?
- sqlite - 如何查找客户订购的大于一定数量的产品列表?
- c# - C# 调整窗口大小问题
- apache-kafka - 如何从 kafka 连接日志文件中检查谁是活动控制器(代理 id)
- cassandra - 如何使用开始和结束令牌范围运行压缩
- reactjs - 当我更新子组件的状态变量时,为什么会导致无限循环?
- python - 在python上追加(0)
- youtube - 使用 YouTube Live Stream API 操作流指标