Node.js 将 MySQL 与 Socket.io 一起使用时脚本冻结而不会崩溃
Node.js script freezes when using MySQL with Socket.io without crashing
我是 Node.js 的超级新手,来自 PHP 背景,但我目前正在从事一个项目,该项目需要在 Web 服务器和浏览器之间进行某种开放式通信。
该脚本旨在发出两组数据:一组与打卡员工列表相匹配的预定员工列表,以及一组与车辆状态相关的数据。由于我无法控制的原因,预定的人员和车辆数据位于 MySQL 服务器上,打卡数据位于单独的 MsSQL 服务器上。
我遇到的问题是,虽然脚本按预期执行,但在一定时间后(有时是几分钟,有时是一天)它就会停止执行任何操作。函数的 setInterval 计时器停止,它停止为客户端 socket.io.js 页面提供服务。
我认为这是我管理我的 SQL 连接的方式,但我不完全确定,即使我是,我也不确定我哪里出错了。没有错误打印到控制台。我花了几个小时试图找到解决方案,但一直未能找到符合我情况的任何东西。
这是完整的代码(出于安全原因更改了 SQL 连接信息)。
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http, {
forceNew: true
});
var moment = require('moment');
var mssql = require('mssql');
var mssql_connection = new mssql.ConnectionPool({
pool: {
max: 10
},
server: 'hostname',
user: 'user',
password: 'password',
database: 'database'
});
mssql_connection.connect();
var mysql = require('mysql');
var mysql_connection = mysql.createPool({
connectionLimit: 20,
host: 'hostname',
user: 'user',
password: 'password',
database: 'database'
});
app.get('/', function (req, res) {
red.end();
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
// Create function to refresh all data that must be grabbed every 5 seconds.
function refreshSchedule() {
return new Promise(function (resolve, reject) {
try {
mysql_connection.getConnection(function (err, connection) {
// Query MySQL database for timepunch entries matching MsSQL results.
connection.query('SELECT * FROM view_schedule WHERE active = 1 AND start <= ' + moment().format("X") + ' AND finish > ' + moment().format("X") + ' ORDER BY job,start ASC', function (err, mysql_result, fields) {
if (err) {
connection.release();
console.log(err);
return;
}
resolve(mysql_result);
});
});
} catch (e) {
console.log(e);
}
});
}
function refreshTimeclock(schedule) {
return new Promise(function (resolve, reject) {
var timestamp = moment().format("X") - (60 * 60 * 12);
const request = new mssql.Request(mssql_connection);
request.query('SELECT SCHDHISTID,DATETIMESTART,DATETIMEEND,PERSID,PERSCODE,LNAME,FNAME FROM dbo.VWSCHDHIST WHERE DATETIMESTART >= \'' + moment(timestamp, "X").format("YYYY-MM-DD HH:mm:ss.SSS") + '\'', (err, mssql_result) => {
if (err) {
connection.release();
console.log(err);
return;
}
var process_schedule = schedule;
var process_timepunch = mssql_result.recordset;
var output = [];
for (i = 0; i < process_schedule.length; i++) {
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (NTD)", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (ND)", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (NT)", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (Maint)", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" ^^", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (Jr./NTD)", "");
for (j = 0; j < process_timepunch.length; j++) {
if (process_schedule[i].fullname == (process_timepunch[j].FNAME + " " + process_timepunch[j].LNAME)) {
process_schedule[i].punchin = moment(process_timepunch[j].DATETIMESTART, "YYYY-MM-DD HH:mm:ss.SSS").format("X");
if (process_timepunch[j].DATETIMEEND) {
process_schedule[i].punchout = moment(process_timepunch[j].DATETIMEEND, "YYYY-MM-DD HH:mm:ss.SSS").format("X");
} else {
process_schedule[i].punchout = null;
}
}
}
output.push(process_schedule[i]);
}
resolve(output);
});
});
}
function refreshVehicles() {
return new Promise(function (resolve, reject) {
try {
mysql_connection.getConnection(function (err, connection) {
// Query MySQL database for timepunch entries matching MsSQL results.
connection.query('SELECT * FROM data_vehicles WHERE number > 0', function (err, mysql_result, fields) {
if (err) {
connection.release();
console.log(err);
return;
}
resolve(mysql_result);
});
});
} catch (e) {
console.log(e);
}
});
}
setInterval(function () {
refreshSchedule().then(function (result) {
refreshTimeclock(result).then(function (output) {
console.log("Schedule: " + moment().format("HH:mm:ss"));
io.emit('updateSchedule', output);
});
});
}, 15000);
setInterval(function () {
refreshVehicles().then(function (output) {
console.log("Vehicles: " + moment().format("HH:mm:ss"));
io.emit('updateVehicles', output);
});
}, 15000);
io.on('connection', function (socket) {
console.log('a user connected');
});
感谢任何帮助,即使只是方向正确的一点也可能在这一点上有所帮助。
上面的代码一团糟,我在排错的过程中确实清理了很多,但最后还是问题不断。
最终在家里设置了一个 Node.js 服务器,但没有重现同样的问题。我最终意识到问题出在我的托管服务提供商 (Dreamhost) 端。我已将 Node.js 组件移至 DigitalOcean,运行 好几天了。
我是 Node.js 的超级新手,来自 PHP 背景,但我目前正在从事一个项目,该项目需要在 Web 服务器和浏览器之间进行某种开放式通信。
该脚本旨在发出两组数据:一组与打卡员工列表相匹配的预定员工列表,以及一组与车辆状态相关的数据。由于我无法控制的原因,预定的人员和车辆数据位于 MySQL 服务器上,打卡数据位于单独的 MsSQL 服务器上。
我遇到的问题是,虽然脚本按预期执行,但在一定时间后(有时是几分钟,有时是一天)它就会停止执行任何操作。函数的 setInterval 计时器停止,它停止为客户端 socket.io.js 页面提供服务。
我认为这是我管理我的 SQL 连接的方式,但我不完全确定,即使我是,我也不确定我哪里出错了。没有错误打印到控制台。我花了几个小时试图找到解决方案,但一直未能找到符合我情况的任何东西。
这是完整的代码(出于安全原因更改了 SQL 连接信息)。
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http, {
forceNew: true
});
var moment = require('moment');
var mssql = require('mssql');
var mssql_connection = new mssql.ConnectionPool({
pool: {
max: 10
},
server: 'hostname',
user: 'user',
password: 'password',
database: 'database'
});
mssql_connection.connect();
var mysql = require('mysql');
var mysql_connection = mysql.createPool({
connectionLimit: 20,
host: 'hostname',
user: 'user',
password: 'password',
database: 'database'
});
app.get('/', function (req, res) {
red.end();
});
http.listen(3000, function () {
console.log('listening on *:3000');
});
// Create function to refresh all data that must be grabbed every 5 seconds.
function refreshSchedule() {
return new Promise(function (resolve, reject) {
try {
mysql_connection.getConnection(function (err, connection) {
// Query MySQL database for timepunch entries matching MsSQL results.
connection.query('SELECT * FROM view_schedule WHERE active = 1 AND start <= ' + moment().format("X") + ' AND finish > ' + moment().format("X") + ' ORDER BY job,start ASC', function (err, mysql_result, fields) {
if (err) {
connection.release();
console.log(err);
return;
}
resolve(mysql_result);
});
});
} catch (e) {
console.log(e);
}
});
}
function refreshTimeclock(schedule) {
return new Promise(function (resolve, reject) {
var timestamp = moment().format("X") - (60 * 60 * 12);
const request = new mssql.Request(mssql_connection);
request.query('SELECT SCHDHISTID,DATETIMESTART,DATETIMEEND,PERSID,PERSCODE,LNAME,FNAME FROM dbo.VWSCHDHIST WHERE DATETIMESTART >= \'' + moment(timestamp, "X").format("YYYY-MM-DD HH:mm:ss.SSS") + '\'', (err, mssql_result) => {
if (err) {
connection.release();
console.log(err);
return;
}
var process_schedule = schedule;
var process_timepunch = mssql_result.recordset;
var output = [];
for (i = 0; i < process_schedule.length; i++) {
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (NTD)", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (ND)", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (NT)", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (Maint)", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" ^^", "");
process_schedule[i].fullname = process_schedule[i].fullname.replace(" (Jr./NTD)", "");
for (j = 0; j < process_timepunch.length; j++) {
if (process_schedule[i].fullname == (process_timepunch[j].FNAME + " " + process_timepunch[j].LNAME)) {
process_schedule[i].punchin = moment(process_timepunch[j].DATETIMESTART, "YYYY-MM-DD HH:mm:ss.SSS").format("X");
if (process_timepunch[j].DATETIMEEND) {
process_schedule[i].punchout = moment(process_timepunch[j].DATETIMEEND, "YYYY-MM-DD HH:mm:ss.SSS").format("X");
} else {
process_schedule[i].punchout = null;
}
}
}
output.push(process_schedule[i]);
}
resolve(output);
});
});
}
function refreshVehicles() {
return new Promise(function (resolve, reject) {
try {
mysql_connection.getConnection(function (err, connection) {
// Query MySQL database for timepunch entries matching MsSQL results.
connection.query('SELECT * FROM data_vehicles WHERE number > 0', function (err, mysql_result, fields) {
if (err) {
connection.release();
console.log(err);
return;
}
resolve(mysql_result);
});
});
} catch (e) {
console.log(e);
}
});
}
setInterval(function () {
refreshSchedule().then(function (result) {
refreshTimeclock(result).then(function (output) {
console.log("Schedule: " + moment().format("HH:mm:ss"));
io.emit('updateSchedule', output);
});
});
}, 15000);
setInterval(function () {
refreshVehicles().then(function (output) {
console.log("Vehicles: " + moment().format("HH:mm:ss"));
io.emit('updateVehicles', output);
});
}, 15000);
io.on('connection', function (socket) {
console.log('a user connected');
});
感谢任何帮助,即使只是方向正确的一点也可能在这一点上有所帮助。
上面的代码一团糟,我在排错的过程中确实清理了很多,但最后还是问题不断。
最终在家里设置了一个 Node.js 服务器,但没有重现同样的问题。我最终意识到问题出在我的托管服务提供商 (Dreamhost) 端。我已将 Node.js 组件移至 DigitalOcean,运行 好几天了。