首页 > 解决方案 > React 事件源未关闭

问题描述

我对 Web 开发和服务器发送事件特别陌生,所以我可能遗漏了一些明显的东西。我正在尝试在带有服务器发送事件的 React 页面上显示一个记录器,它工作正常,但我无法关闭 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)
    }
  }

控制台按预期记录“关闭的事件源”,并且日志挂钩不再更新,但请求不断从某个地方触发。我错过了什么?

请求由这样的烧瓶服务器处理(只需发送一些虚拟日志):

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")

服务器日志:

<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

标签: javascriptreactjsserver-sent-events

解决方案


最后,我找到了一种解决方法(不过,我仍然不明白为什么最初的方法不起作用)。我没有使用挂钩来存储 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: 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")

推荐阅读