I'm quite new to web development and server-sent-events in particular so probably I'm missing something obvious. I'm trying to display a logger on a React page with server-sent-events, which works fine, but I cannot close the eventSource. The server continuously receives requests after eventSource.close() was called.
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)
}
}
The console logs "closed eventsource" as expected and the logs hook is not updated any longer, but the requests keep getting fired from somewhere. What am I missing?
The requests are handled by a flask server like this (just send some dummy logs):
def log_progress():
for i in range(10):
message = 'data: step {} \n\n'.format(i)
yield message
time.sleep(1)
yield 'data: finished\n\n'
@app.route("/logs")
def stream_logs():
return = Response(log_progress(), mimetype="text/event-stream")
The server log:
<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
I'm quite new to web development and server-sent-events in particular so probably I'm missing something obvious. I'm trying to display a logger on a React page with server-sent-events, which works fine, but I cannot close the eventSource. The server continuously receives requests after eventSource.close() was called.
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)
}
}
The console logs "closed eventsource" as expected and the logs hook is not updated any longer, but the requests keep getting fired from somewhere. What am I missing?
The requests are handled by a flask server like this (just send some dummy logs):
def log_progress():
for i in range(10):
message = 'data: step {} \n\n'.format(i)
yield message
time.sleep(1)
yield 'data: finished\n\n'
@app.route("/logs")
def stream_logs():
return = Response(log_progress(), mimetype="text/event-stream")
The server log:
<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
Share
Improve this question
edited Oct 2, 2020 at 9:23
Nils
asked Oct 2, 2020 at 9:05
NilsNils
711 silver badge6 bronze badges
1 Answer
Reset to default 6Finally, I found a workaround (I still don't understand why the initial approach did not work, though). Instead of using a hook to store the eventListener, I handled everything in the useEffect hook that is called on mount using 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() )
}, [])
And on the server, I've added event types:
def log_progress():
for i in range(10):
message = 'event: newEntry\n'
message += 'data: step {} \n\n'.format(i)
yield message
time.sleep(1)
yield 'event: close\ndata: finished \n\n'
@app.route("/logs")
def stream_logs():
return = Response(log_progress(), mimetype="text/event-stream")