#javascript #reactjs #server-sent-events
#javascript #reactjs #отправленные сервером события
Вопрос:
Я новичок в веб-разработке и, в частности, в отправленных сервером событиях, поэтому, вероятно, я упускаю что-то очевидное. Я пытаюсь отобразить регистратор на странице реакции с помощью отправленных сервером событий, который работает нормально, но я не могу закрыть EventSource. Сервер непрерывно получает запросы после вызова EventSource.close() .
const [eventSource, setEventSource] = React.useState(new EventSource("http://localhost:5001/logs"))
const [logs, setLogs] = React.useState([])
React.useEffect(() => {
eventSource.onmessage = e => updateLogs((e.data))
return (() => eventSource.close() )
}, [])
const updateLogs = (entry) => {
setLogs(logs => [...logs, entry])
if (entry === 'finished'){
eventSource.close()
console.log('closed eventsource')
setEventSource(null)
}
}
Консоль регистрирует «закрытый eventsource», как и ожидалось, и перехват журналов больше не обновляется, но запросы продолжают откуда-то запускаться. Чего мне не хватает?
Запросы обрабатываются сервером flask следующим образом (просто отправьте несколько фиктивных журналов):
def log_progress():
for i in range(10):
message = 'data: step {} nn'.format(i)
yield message
time.sleep(1)
yield 'data: finishednn'
@app.route("/logs")
def stream_logs():
return = Response(log_progress(), mimetype="text/event-stream")
Журнал сервера:
<Response streamed [200 OK]>
127.0.0.1 - - [02/Oct/2020 11:00:22] "GET /logs HTTP/1.1" 200 -
<Response streamed [200 OK]>
127.0.0.1 - - [02/Oct/2020 11:00:22] "GET /logs HTTP/1.1" 200 -
<Response streamed [200 OK]>
127.0.0.1 - - [02/Oct/2020 11:00:22] "GET /logs HTTP/1.1" 200 -
<Response streamed [200 OK]>
127.0.0.1 - - [02/Oct/2020 11:00:23] "GET /logs HTTP/1.1" 200 -
<Response streamed [200 OK]>
127.0.0.1 - - [02/Oct/2020 11:00:23] "GET /logs HTTP/1.1" 200 -
// this keeps on forever until page is closed
Ответ №1:
Наконец, я нашел обходной путь (я до сих пор не понимаю, почему первоначальный подход не сработал). Вместо того, чтобы использовать перехват для хранения EventListener, я обработал все в перехвате useEffect, который вызывается при монтировании с помощью addEventListener():
React.useEffect(() => {
let eventSource = new EventSource("http://localhost:5001/logs")
// eventSource.onmessage = event => updateLogs((event.data))
eventSource.addEventListener('newEntry', e =>
updateLogs(e.data)
)
eventSource.addEventListener('close', () =>
eventSource.close()
)
return (() => eventSource.close() )
}, [])
И на сервере я добавил типы событий:
def log_progress():
for i in range(10):
message = 'event: newEntryn'
message = 'data: step {} nn'.format(i)
yield message
time.sleep(1)
yield 'event: closendata: finished nn'
@app.route("/logs")
def stream_logs():
return = Response(log_progress(), mimetype="text/event-stream")