У меня есть очень простая служба узла, предоставляющая конечную точку, предназначенную для использования соединения Server Send Events (SSE), и очень простой клиент ReactJs, использующий его через EventSource.onmessage.
Во-первых, когда я устанавливаю точку отладки в updateAmountState (Chrome Dev), я не вижу ее вызова.
Во-вторых, я получаю net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (ОК). Согласно https://github.com/aspnet/KestrelHttpServer/issues/1858 "ERR_INCOMPLETE_CHUNKED_ENCODING в chrome обычно означает, что неперехваченное исключение было выброшено из приложения в середине записи в тело ответа». Затем я проверил серверную часть, чтобы увидеть, не нахожу ли я какую-либо ошибку. Что ж, я установил точку останова в нескольких местах в server.js в обоих setTimeout(() => {... и я вижу, что он запускается периодически. Я ожидал, что каждая строка будет запускаться только один раз. Так что, похоже, интерфейс пытаясь постоянно вызывать бэкэнд и получая какую-то ошибку.
Все приложение, как внешнее в ReactJ, так и сервер в NodeJ, можно найти на https://github.com/jimisdrpc/hello-pocker-coins.
серверная часть:
const http = require("http");
http
.createServer((request, response) => {
console.log("Requested url: " + request.url);
if (request.url.toLowerCase() === "/coins") {
response.writeHead(200, {
Connection: "keep-alive",
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache"
});
setTimeout(() => {
response.write('data: {"player": "Player1", "amount": "90"}');
response.write("\n\n");
}, 3000);
setTimeout(() => {
response.write('data: {"player": "Player2", "amount": "95"}');
response.write("\n\n");
}, 6000);
} else {
response.writeHead(404);
response.end();
}
})
.listen(5000, () => {
console.log("Server running at http://127.0.0.1:5000/");
});
внешний интерфейс:
import React, { Component } from "react";
import ReactTable from "react-table";
import "react-table/react-table.css";
import { getInitialCoinsData } from "./DataProvider";
class App extends Component {
constructor(props) {
super(props);
this.state = {
data: getInitialCoinsData()
};
this.columns = [
{
Header: "Player",
accessor: "player"
},
{
Header: "Amount",
accessor: "amount"
}
];
this.eventSource = new EventSource("coins");
}
componentDidMount() {
this.eventSource.onmessage = e =>
this.updateAmountState(JSON.parse(e.data));
}
updateAmountState(amountState) {
let newData = this.state.data.map(item => {
if (item.amount === amountState.amount) {
item.state = amountState.state;
}
return item;
});
this.setState(Object.assign({}, { data: newData }));
}
render() {
return (
<div className="App">
<ReactTable data={this.state.data} columns={this.columns} />
</div>
);
}
}
export default App;
Исключение, которое я вижу в хроме:
Итак, мой прямой вопрос: почему я получаю ERR_INCOMPLETE_CHUNKED_ENCODING 200? Я что-то упустил в бэкэнде или во внешнем интерфейсе?
Некоторые советы могут мне помочь:
Почему я вижу websocket в статусе oending, если я вообще не использую websocket? Я знаю основную разницу (веб-сокет является двусторонним, спереди назад и сзади вперед, и это другой протокол, в то время как SSE работает через http и работает только сзади). Но я вообще не собираюсь использовать веб-сокет. (см. синюю линию на принтскрине ниже)
Почему я вижу, что источник событий с 0 байтами и 236 байтами не прошел. Я понимаю, что источник событий — это именно то, что я пытаюсь использовать, когда закодировал «this.eventSource = new EventSource («монеты»);». (см. строку чтения на принтскрине ниже)
Очень странно, по крайней мере для меня, некоторое время, когда я убивал подачу, я мог видеть вызванный метод updateAmountState.
Если вызвать localhost: 5000/coins в браузере, я вижу, что сервер отвечает на ответ (обе строки json). Могу ли я предположить, что я правильно закодировал сервер, а ошибки - это что-то исключительно во внешнем интерфейсе?