首页 > 解决方案 > 将 MySQL 与 Socket.io 一起使用时,Node.js 脚本会冻结而不会崩溃

问题描述

我是 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.jssocket.ionode-mysqlnode-mssql

解决方案


上面的代码是一团糟,我在对其进行故障排除的过程中确实清理了很多,但最后问题仍然存在。

最终在家里设置了一个 Node.js 服务器,它没有重现同样的问题。我最终意识到问题在于我的托管服务提供商(Dreamhost)。此后,我将 Node.js 组件移至 DigitalOcean,并且它运行了好几天。


推荐阅读