新手一名,遇到问题,困扰了一天了,帮忙看看是什么问题啊 直接上code html:
<table class="ui selectable celled table segment" id="tbEventMessage">
<thead>
<tr>
<th>Event ID</th>
<th>Precursor Id</th>
<th>DataItem Id</th>
<th>Zone Number</th>
<th>Condition Id</th>
<th>SubCondition Id</th>
<th>State</th>
<th>Active Time</th>
<th>Event Time</th>
<th>Severity</th>
<th>Threshold</th>
<th>Message</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot class="full-witdh">
<tr>
<th colspan="3">
<a class="ui right labeled icon button" href="/eventMessages/create">
<i class="user icon"></i>Add eventMessage
</a>
</th>
</tr>
</tfoot>
</table>
Javascript:
var messageTable = $('#tbEventMessage').DataTable({
ajax:{
url: "/eventMessages",
type: "get",
dataSrc: ""
},
columns : [
{data: 'EventID'},
{data: 'PrecursorId'},
{data: 'DataItemId'},
{data: 'ZoneNumber'},
{data: 'ConditionId'},
{data: 'SubConditionId'},
{data: 'State'},
{data: 'ActiveTime', render: function(data){
return data.replace(/T/, ' ').replace(/\..+/, '');
}
},
{data: 'EventTime', render: function(data){
return data.replace(/T/, ' ').replace(/\..+/, '');
}
},
{data: 'Severity'},
{data: 'Threshold'},
{data: 'Message'}
],
createdRow: function(row, data, index) {
var severity = data['Severity'];
if (severity >= 700) {
$('td',row).css('background-color', "crimson");
}else if(severity >= 400){
$('td',row).css('background-color', "#FA8072");
}else if (severity >= 100){
$('td',row).css('background-color', "coral");
}else{
$('td',row).css('background-color', "#4FC08D");
}
}
});
setTimeout(refresh, 1000);
function refresh() {
//ajax
messageTable.ajax.reload();
setTimeout(refresh, 1000);
}
model:
const sql = require('mssql');
var config = {
user: 'sa',
password: 'porta',
server: 'CN10LT099',
database: 'ClairAlarm',
pool: {
max: 10,
min: 0,
idleTimeoutMillis: 30000
}
};
module.exports = {
closeConnection: function closeConnection() {
sql.close();
},
getEventMessages: function getEventMessages(limit) {
//console.log(limit);
return new sql.ConnectionPool(config).connect().then(pool => {
// Query
return pool.request()
.input('recordlimit', sql.Int, parseInt(limit))
.execute('ReadEventMessage')
}).then(result => {
//pool.close();
return result.recordset;
}).catch(err => {
//pool.close();
console.trace(err);
});
}
};
eventMessages.js
var express = require('express');
var router = express.Router();
var EventMessageModel = require('../models/eventMessages');
var checkLogin = require('../middlewares/check.js').checkLogin;
// GET /eventMessages
router.get('/', function(req, res, next) {
EventMessageModel.getEventMessages(20)
.then(function(eventMessages) {
//console.dir(eventMessages);
//res.end(JSON.stringify(eventMessages));
res.json(eventMessages);
});
//.catch(next);
});
module.exports = router;
@2VCl1md 谢谢,我知道是这个相关的问题,就是找不到哪里错了啊,我这边用的是res.json(), 这个有问题吗?
@newonejoe 应该是吧,我之前也遇到过这个问题
我的问题好像和同一个页面的两个ajax有关系, 两个ajax会有冲突吗?我真的是个小白,帮我看看吧
<script type="text/javascript">
// 使通知框延时自动从页面删除
$(document).ready( function () {
// 延时清除掉成功、失败提示信息
if ($('.ui.success.message').length > 0) {
$('.ui.success.message').fadeOut(1000)
} else if ($('.ui.error.message').length > 0) {
$('.ui.error.message').fadeOut(1000)
}
// 鼠标悬浮在头像上,弹出气泡提示框
$('.post-content .avatar-link').popup({
inline: true,
position: 'bottom right',
lastResort: 'bottom right'
});
// datatable
//$('.ui.table').DataTable();
//var table = $('.ui.table').DataTable({
// ajax: '/data/arrays.txt'
//});
$('.ui.accordion').accordion();
//var messageTable = $('#tbEventMessage').DataTable();
var messageTable = $('#tbEventMessage').DataTable({
ajax:{
url: "/eventMessages",
//type: "get",
async: false,
dataSrc: ""
},
columns : [
{data: 'EventID'},
{data: 'PrecursorId'},
{data: 'DataItemId'},
{data: 'ZoneNumber'},
{data: 'ConditionId'},
{data: 'SubConditionId'},
{data: 'State'},
{data: 'ActiveTime', render: function(data){
return data.replace(/T/, ' ').replace(/\..+/, '');
}
},
{data: 'EventTime', render: function(data){
return data.replace(/T/, ' ').replace(/\..+/, '');
}
},
{data: 'Severity'},
{data: 'Threshold'},
{data: 'Message'}
],
createdRow: function(row, data, index) {
var severity = data['Severity'];
if (severity >= 700) {
$('td',row).css('background-color', "crimson");
}else if(severity >= 400){
$('td',row).css('background-color', "#FA8072");
}else if (severity >= 100){
$('td',row).css('background-color', "coral");
}else{
$('td',row).css('background-color', "#4FC08D");
}
}
});
/*
setTimeout(refresh, 1000);
function refresh() {
//ajax
messageTable.ajax.reload();
setTimeout(refresh, 1000);
}
*/
// side bar
//$('#menu').click(function() {
// $('.ui.sidebar').sidebar('toggle');
//});
//
$('.ui.sidebar').first()
.sidebar('attach events', '.launch.button');
// 点击按钮弹出下拉框
$(' .ui .dropdown').dropdown();
// auto change text according to Name and Device
$('#dataItemType').keypress(function() {
var total = $('#dataItemDevice>option:selected').html() + "//" + $(this).val();
$('#dataItemFullPath').val(total);
});
$('#dataItemDevice').change(function(){
var total = $('#dataItemDevice>option:selected').html() + "//" + $('#dataItemType').val();
$('#dataItemFullPath').val(total);
});
// refresh the content
//setTimeout(eventMessageRefresh, 1000);
/*
$('#container').highcharts({
series: [{
},{
},{
},{
}]
});
// the button action
var i = 0;
$('#button').click(function () {
var chart = $('#container').highcharts();
chart.series[0].addPoint(50 * (i % 3));
i += 1;
});
*/
/* Get the DataItems List*/
var DataItems = $.ajax()
Highcharts.setOptions({
global: {
useUTC: false
}
});
Highcharts.chart('container', {
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
/*load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.random();
//series.addPoint([x, y], true, true);
if (series.data.length < 300) {
series.addPoint([x, y]);
}else
{
series.addPoint([x, y], true, true);
}
}, 1000);
}*/
load: function() {
// ajax code
var cur_series = this.series;
setInterval( function() {
$.ajax({
type:"get",
url:"/analogCharts/",
async:true,
success: function(datum){
//console.log(datum[0].Value);
for (var i = 0; i < datum.length; i++) {
console.dir(data);
var data = datum[i];
var serieId = data.DataItemId-1;
var newPoint_X_String = (data.TimeStamp).replace(/T/, ' ').replace(/\..+/, '');
var newPoint_X = (new Date(newPoint_X_String)).getTime();
var newPoint_Y = data.Value;
var serie = cur_series[serieId],
len = serie.points.length;
//var lastPoint_X = serie.data[len-1].x,
// lastPoint_Y = serie.data[len-1].y;
if (len > 0) {
var lastPoint_X = serie.points[len-1].x,
lastPoint_Y = serie.points[len-1].y;
} else{
var lastPoint_X = 0,
lastPoint_Y = 0;
}
if (lastPoint_X < newPoint_X) {
if (len < 300) {
serie.addPoint([newPoint_X, newPoint_Y]);
} else {
serie.addPoint([newPoint_X, newPoint_Y], true, true);
}
} else {
if (len < 300) {
serie.addPoint([lastPoint_X + 1000, 0]);
} else {
serie.addPoin([lastPoint_X + 1000, 0], true, true);
}
}
}
}
});}, 1000);
//setTimeout
//setTimeout(load(), 5000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: true
},
exporting: {
enabled: true
},
series: [{
name: '压差',
data: []
},{
name: '风机电流',
data: []
},{
name: '袋漏定位',
data: []
},{
name: '粉尘排放',
data: []
}],
credits: {
enabled: false
}
});
setInterval(function () {
//alert("Hi");
messageTable.ajax.reload();
}, 5000);
})
//function eventMessageRefresh(){
//
//console.log("Refresh");
//}
</script>
很奇怪的情况,你可以试试改成res.send测试一下 这是res.json我查到的部分解释https://segmentfault.com/q/1010000009000325/a-1020000009003036 是否有可能是因为res.json最后的set导致的? 我觉得最起码两个Ajax不会冲突吧
跟ajax应该没关系,看起来也不像是res.json的问题,我猜应该是别的地方有个异步的end操作
@Yuki-Minakami 目前我修改了两个地方,现在没有这个报错了
-
把两个ajax都设置为同步的方式 async = false, 我过会儿再试一下打开会是怎样
-
在router中去掉了next,改为了
router.get(’/’, function(req, res) { EventMessageModel.getEventMessages(20) .then(function(eventMessages) { res.setHeader(‘Content-Type’, ‘application/json’); res.send(JSON.stringify(eventMessages)); return; }); });
@2linziyi2 谢谢你的回复,我发现两个Ajax在全部设置为异步的时候就发生冲突了,该怎么优化呢?两个Ajax都是放在setInterval里面用来读取实时数据,刷新highchart和datatable的
问题应该是在 then 里面 出现了异常,然后在 catch 中 又执行了 next,导致两次 writeHead 操作。。
你可以試一下
router.get('/', (req, res, next) => EventMessageModel.getEventMessage(20)
// res.json 會設header為json,同時如果eventMessages是object,就不用json。stringify了
.then(res.json)
)
上面可能是我編程的風格,你可以應該在EventMessageModel前加return
router.get('/', function(req, res, next) {
return EventMessageModel.getEventMessages(20)
.then(function(eventMessages) {
res.json(eventMessages);
});
// .catch(next);
// 在router裡面應該就不用catch(next)除非是寫中間件或者你已經知道會有哪些錯誤可能會出現才寫catch來反饋錯誤訊息
});
@alphaXkiller 谢谢您的解释,对于middleware我的理解不够深刻,导致了前面遇到的问题,考虑到实时性,我现在转向用socket.io来实现这个功能,效果还不错
<script>
$(document).ready( function () {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
var messageTable = $('#tbEventMessage').DataTable({
});
function UpdateTable(){
socket.emit('eventRequest', 'update');
}
UpdateTable();
socket.on('chat message', function(msg) {
$('#messages').append($('<li>').text(msg));
});
socket.on('eventCallback', function(feedback){
socket.emit('chat message', 'Received the feedback');
messageTable.clear();
for(var i = 0; i < feedback.length; i++)
{
var data = feedback[i];
socket.emit('chat message', ' Record: ' + data.EventID);
messageTable.row.add([
data.EventID,
data.PrecursorId,
data.DataItemId,
data.ZoneNumber,
data.ConditionId,
data.SubConditionId,
data.State,
(data.ActiveTime).replace(/T/, ' ').replace(/\..+/, ''),
(data.EventTime).replace(/T/, ' ').replace(/\..+/, ''),
data.Severity,
data.Threshold,
data.Message
]).draw(false);
}
});
});
</script>
index.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var EventMessageModel = require('./models/eventMessages');
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket) {
console.log('a user connected');
socket.on('disconnect', function() {
console.log('user disconnected');
});
socket.on('chat message', function(msg){
console.log('message: ' + msg);
io.emit('chat message', msg);
});
socket.on('eventRequest', function(msg){
console.log('eventRequest:' + msg);
EventMessageModel.getEventMessages(20).then(function(eventMessages) {
io.emit('eventCallback', eventMessages);
});
})
});
http.listen(3000, function() {
console.log('listen on *3000');
});
@newonejoe socket.io是用來处理实时数据交换,譬如是聊天室,股票数据呈现之类的。如果只是用于提交表格的话,socket.io可能会导致资源浪费
@alphaXkiller 我用socket.io个来推送warning/error 信息到HMI,实时性要求高一点, 表格只是显示的手段,没有数据提交