Я настроил http-сервер для отправки данных с интервалом в 20 секунд. Данные начинаются с 101, и это число увеличивается каждый раз. Таким образом, последовательность чисел будет 101,102,103 и т. Д. c
. Я также добавляю данные после a; разделитель, отметка времени, когда сервер отправляет данные.
Я думаю, что у меня есть ошибка в моем коде javascript, потому что я наблюдаю это поведение:
http-сервер отправляет данные "105" в 12: 28: 52.654
на моей веб-странице я вижу элемент данных «105» в 12: 29: 12: 690, ie 20 секунд спустя. 20 секунд - это интервал отправки данных. Таким образом, похоже, что функция onmessage EventSource вызывается, но обрабатывает предыдущий элемент данных, в данном случае «104».
Код веб-страницы:
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
let source = new EventSource('/startmonitoring');
function startCallMonitoring(){
source.onmessage = function(event) {
console.log(event.data);
addCall(event.data);
};
source.addEventListener('error', function(e) {
if (e.readyState == EventSource.CLOSED) {
console.log("closed");
}
}, false);
}
function stopCallMonitoring() {
source.close();
}
function gettime() {
var currentDate = new Date();
var hour = currentDate.getHours();
var minute = currentDate.getMinutes();
var second = currentDate.getSeconds();
var millisecond = currentDate.getMilliseconds();
return pad(hour) + ":" + pad(minute) + ":" + pad(second) + "." + millisecond;
}
function getdate() {
var currentDate = new Date();
var date = currentDate.getDate();
var month = currentDate.getMonth(); //Be careful! January is 0 not 1
var year = currentDate.getFullYear();
return pad(date) + "/" + pad(month + 1) + "/" + pad(year);
}
function pad(n) {
return n<10 ? '0'+n : n;
}
function addCall(callerid) {
// insert new row.
var tableref = document.getElementById('CallsTable').getElementsByTagName('tbody')[0];
var newrow = tableref.insertRow(0);
var datecell = newrow.insertCell(0);
var timecell = newrow.insertCell(1);
var calleridcell = newrow.insertCell(2);
var customerlinkcell = newrow.insertCell(3);
datecell.innerHTML = getdate();
timecell.innerHTML = gettime();
calleridcell.innerHTML = callerid;
customerlinkcell.innerHTML = "customerlink";
console.log("added " + callerid + " at " + gettime());
}
</script>
</head>
<body>">
<button onclick="startCallMonitoring()">Start Call Monitoring</button>
<button onclick="stopCallMonitoring()">Stop Call Monitoring</button>
<table id="CallsTable">
<thead>
<tr>
<th>Date</th>
<th>Time added to table</th>
<th>CallerID</th>
<th>link</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
</body>
</html>
Снимок экрана потока событий в Chrome средствах разработки.
Почему такое поведение? Как я могу это исправить?
Дополнительная информация о серверной части.
Я сам написал http-сервер, чтобы это могло быть причиной. Без отправки всего кода для сервера, который является довольно большим, вот код, использующий некоторые вспомогательные функции для создания ответного сообщения HTTP.
Этот timerfun c вызывается каждые 20 секунд.
Обычно, когда я вижу в консоли сервера вывод:
timerfunc() - sending: HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 29
Cache-Control: no-cache
Content-Type: text/event-stream
Access-Control-Allow-Origin: *
id: 7
data: 106;12:29:12.689
to 192
Затем в веб-браузере заполняется элемент данных 105.
void http_server::timerfunc() {
http_response rs;
rs.status = 200;
rs.set_version(1, 1);
rs.add_header("Connection", "keep-alive");
rs.add_header("Content-Type", "text/event-stream"); // this is REQUIRED
//header('Cache-Control: no-cache');
rs.add_header("Cache-Control", "no-cache"); // not sure if required, investigate what it does
rs.add_header("Access-Control-Allow-Origin", "*"); // think because for node.js demo was on different network - don't think need this
//rs.add_header("Transfer-Encoding", "chunked"); // doesn't work if you don't do chunking - investigate - but don't need
static unsigned number = 100;
std::string callerid = std::to_string(number);
char timebuf[50] = {};
get_timestamp(timebuf);
rs.set_body("id: 7\ndata: " + callerid + ";" + timebuf + "\n");
rs.set_content_length_to_body_length();
unsigned retcode = 0;
const size_t len = rs.get_content_length();
for (auto client : clients) {
std::string s = codec.make_http_response_message(rs);
retcode = send(client, s.c_str(), s.length());
std::cout << "timerfunc() - sending: " << s << " to " << client << std::endl;
}
number++;
if (number == 999)
number = 100;
}