问题描述
我对Web开发和服务器发送事件特别陌生,因此可能缺少明显的东西。我试图在带有服务器已发送事件的React页面上显示记录器,该记录器工作正常,但无法关闭eventSource。调用eventSource.close()后,服务器会不断接收请求。
@name Circle#getName
控制台将按预期方式记录“关闭的事件源”,并且不再更新日志钩子,但是不断从某处触发请求。我想念什么?
请求由类似这样的烧瓶服务器处理(只需发送一些虚拟日志):
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")
解决方法
最后,我找到了解决方法(不过,我仍然不明白为什么最初的方法不起作用)。我没有使用钩子来存储eventListener,而是使用了addEventListener()在挂载时调用的useEffect钩子中处理了所有内容:
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")