我正在尝试使用来自数据库 Mysql 的服务器发送事件获取实时数据并将值发送到客户端 Reactjs。这是代码:
服务器.js
const mysql = require('mysql');
const app = require('express')()
const fetch = require('node-fetch');
const con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'databasetest',
});
var increment = 0;
app.get('/stream/:abc/:qwe', (request, response) => {
console.log(`Request url: ${request.url}`);
var startDate = request.params.abc
var endDate = request.params.qwe
request.on('close', () => {
increment = increment - 1;
closeConnection(response);
});
response.writeHead(200, {
'Connection': 'keep-alive',
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Access-Control-Allow-Origin': '*'
});
setTimeout(() => {
var initial_result;
console.log("The connection number is ", (++increment))
setInterval(() => {
con.query('SELECT * FROM status_table where start_time BETWEEN ? and ?', [startDate, endDate], (err, rows) => {
if (err) {
console.log('error', err.message, err.stack)
}
if (JSON.stringify(rows) === JSON.stringify(initial_result)) {
} else {
if (Changed(initial_result, rows)) {
let data = null;
const url = "http://localhost:8080/data?startTime=" + startDate + "&endTime=" + endDate;
data = getData(url);
data.then(function (result) {
console.log("Data is sent")
response.write("event: executinghello\n");
response.write('data: ' + JSON.stringify(result));
response.write("\n\n");
eventHistory.push(result);
response.end()
})
initial_result = rows;
}
}
})
function Changed(pre, now) {
if (pre != now) {
return true
} else {
return false
}
}
}, 5000);
}, 3000);
});
app.listen(4001, () => console.log('SSE app listening on port 4001!'))
async function getData(url) {
try {
const response = await fetch(url);
const json = await response.json();
return json;
} catch (error) {
console.log(error);
return error;
}
};
function closeConnection(response) {
if (!response.finished) {
response.end();
console.log('Stopped sending events.');
}
}
客户端.js
this.eventSource = new EventSource("http://localhost:4001/stream/"+startDate+"/"+endDate);
this.eventSource.addEventListener("executinghello", e => {
const data = JSON.parse(e.data);
data.sort((a, b) => parseFloat(b.id) - parseFloat(a.id));
this.setState({
isLoaded: true,
allData: data ,
})
});
使用它,我能够获取数据,但几秒钟后连接关闭,然后如果数据正在 POST 到 DB,则会出现以下错误:
Data is sent
events.js:292
throw er; // Unhandled 'error' event
^
Error [ERR_STREAM_WRITE_AFTER_END]: write after end
at write_ (_http_outgoing.js:629:17)
at ServerResponse.write (_http_outgoing.js:621:15)
at Query.<anonymous> (C:\Users\Documents\socket-io-server\app.js:73:24)
at Query.<anonymous> (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\Connection.js:526:10)
at Query._callback (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\Connection.js:488:16)
at Query.Sequence.end (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Query._handleFinalResultPacket (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\sequences\Query.js:149:8)
at Query.EofPacket (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\sequences\Query.js:133:8)
at Protocol._parsePacket (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\Protocol.js:291:23)
at Parser._parsePacket (C:\Users\Documents\socket-io-server\node_modules\mysql\lib\protocol\Parser.js:433:10)
Emitted 'error' event on ServerResponse instance at:
at writeAfterEndNT (_http_outgoing.js:684:7)
at processTicksAndRejections (internal/process/task_queues.js:85:21) {
code: 'ERR_STREAM_WRITE_AFTER_END'
}
不明白我错过了什么,连接自动关闭。如何克服自动连接 end() 问题?以及如何摆脱上述错误?您能否帮助我仅在数据发生更改时才将数据从服务器发送到客户端,如果没有更改,则不应通知客户端?如何管理连接并在不使用时关闭它们?有人可以帮我解决上述所有问题吗?谢谢!