React 应用程序未刷新通过 socket.io 流式传输的日志
React app not refreshing the log streamed through socket.io
在我的项目中,我使用 flask_socketio 作为服务器,使用 socket.io-client 作为客户端。我的 main.py(烧瓶服务器)不断读取不断更新的日志文件(console.log)。在UI中点击开始按钮时,会显示日志文件的数据,但是随着我的日志文件的更新,UI中并没有显示更新后的数据。我必须刷新页面或再次单击按钮才能看到更新后的数据。
我希望日志文件的数据通过单击按钮在 UI 上实时流式传输。如何解决这个问题?
烧瓶代码
from flask import Flask, jsonify
# Needed for localhost testing.
from flask_cors import CORS, cross_origin
from flask_socketio import SocketIO, emit
from time import sleep
import pdb
import json
app = Flask(__name__)
# Socket io setup.
app.config['SECRET_KEY'] = 'secret!'
# |cors_allowed_origins| is required for localhost testing.
socket = SocketIO(app, cors_allowed_origins="*")
# For localhost testing.
CORS(app)
@socket.on('event_stream', namespace='/logConsole')
def test_connect():
def generate():
fname = "./src/console.log"
with open(fname) as f:
yield f.read()
emit_data = next(generate())
socket.sleep(0)
emit('custom-server-msg', {'data': emit_data})
if __name__ == '__main__':
socket.run(app)
反应代码
import React from 'react'
import io from 'socket.io-client'
class App extends React.Component {
state = { startVar: true, setVar: false };
setSocketListeners() {
let socket = io.connect('ws://localhost:5000/logConsole');
socket.emit('event_stream', () => {
console.log("Websocket connected: " + socket.connected)
})
socket.on('custom-server-msg', (data) => {
console.log("Data received: " + data.data)
const setup_logs = data.data;
this.setState({ setup_logs });
})
}
render() {
return (
<div className="App">
<h1>Data from log file</h1>
<button type="button" onClick={() => this.setSocketListeners()}>Start</button>
<p>{this.state.setup_logs}</p>
</div>
);
}
}
export default App;
这是我的浏览器控制台的样子 -->
这是我的后端控制台 -->
在你的 flask 代码中,如果你想连续流式传输,则需要在循环中调用 next(),现在可以通过放置一个带有休眠时间的无限循环来完成,
@socket.on('event_stream')
def test_connect():
def generate():
fname = "./src/console.log"
with open(fname, "r+") as f:
yield f.read()
while True:
emit_data = next(generate())
socket.sleep(2)
emit('custom-server-msg', {'data':emit_data})
否则,如果日志文件过于连续更新,可以使用os.stat(FILE_NAME).st_mtime来检查正在更新的文件的时间戳,如果日志文件中有任何更改,将调用 next() 来流式传输它:
@socket.on('event_stream')
def test_connect():
cached_stamp = 0
def generate():
fname = "./src/console.log"
with open(fname, "r+") as f:
yield f.read()
while True:
stamp = os.stat('./src/console.log').st_mtime
if stamp != cached_stamp:
cached_stamp = stamp
emit_data = next(generate())
emit('topo-server-msg', {'data':emit_data})
在我的项目中,我使用 flask_socketio 作为服务器,使用 socket.io-client 作为客户端。我的 main.py(烧瓶服务器)不断读取不断更新的日志文件(console.log)。在UI中点击开始按钮时,会显示日志文件的数据,但是随着我的日志文件的更新,UI中并没有显示更新后的数据。我必须刷新页面或再次单击按钮才能看到更新后的数据。 我希望日志文件的数据通过单击按钮在 UI 上实时流式传输。如何解决这个问题?
烧瓶代码
from flask import Flask, jsonify
# Needed for localhost testing.
from flask_cors import CORS, cross_origin
from flask_socketio import SocketIO, emit
from time import sleep
import pdb
import json
app = Flask(__name__)
# Socket io setup.
app.config['SECRET_KEY'] = 'secret!'
# |cors_allowed_origins| is required for localhost testing.
socket = SocketIO(app, cors_allowed_origins="*")
# For localhost testing.
CORS(app)
@socket.on('event_stream', namespace='/logConsole')
def test_connect():
def generate():
fname = "./src/console.log"
with open(fname) as f:
yield f.read()
emit_data = next(generate())
socket.sleep(0)
emit('custom-server-msg', {'data': emit_data})
if __name__ == '__main__':
socket.run(app)
反应代码
import React from 'react'
import io from 'socket.io-client'
class App extends React.Component {
state = { startVar: true, setVar: false };
setSocketListeners() {
let socket = io.connect('ws://localhost:5000/logConsole');
socket.emit('event_stream', () => {
console.log("Websocket connected: " + socket.connected)
})
socket.on('custom-server-msg', (data) => {
console.log("Data received: " + data.data)
const setup_logs = data.data;
this.setState({ setup_logs });
})
}
render() {
return (
<div className="App">
<h1>Data from log file</h1>
<button type="button" onClick={() => this.setSocketListeners()}>Start</button>
<p>{this.state.setup_logs}</p>
</div>
);
}
}
export default App;
这是我的浏览器控制台的样子 -->
这是我的后端控制台 -->
在你的 flask 代码中,如果你想连续流式传输,则需要在循环中调用 next(),现在可以通过放置一个带有休眠时间的无限循环来完成,
@socket.on('event_stream')
def test_connect():
def generate():
fname = "./src/console.log"
with open(fname, "r+") as f:
yield f.read()
while True:
emit_data = next(generate())
socket.sleep(2)
emit('custom-server-msg', {'data':emit_data})
否则,如果日志文件过于连续更新,可以使用os.stat(FILE_NAME).st_mtime来检查正在更新的文件的时间戳,如果日志文件中有任何更改,将调用 next() 来流式传输它:
@socket.on('event_stream')
def test_connect():
cached_stamp = 0
def generate():
fname = "./src/console.log"
with open(fname, "r+") as f:
yield f.read()
while True:
stamp = os.stat('./src/console.log').st_mtime
if stamp != cached_stamp:
cached_stamp = stamp
emit_data = next(generate())
emit('topo-server-msg', {'data':emit_data})