最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React eventsource is not closed - Stack Overflow

programmeradmin0浏览0评论

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
Add a ment  | 

1 Answer 1

Reset to default 6

Finally, 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")
发布评论

评论列表(0)

  1. 暂无评论