Опитвам се да направя прост скрипт за изпращане на събития от приложение на python към клиент. Направих Console
React компонент, който използва SocketIO за получаване на събитията, и изпращам съобщенията с Flask SocketIO.
Това е моят app.py
:
from flask import Flask, request
from flask_socketio import SocketIO, send
app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins='*')
@app.route('/send/<int:n>')
def send_n(n):
for i in range(n):
socketio.emit('console', str(i+1))
socketio.sleep(0.1)
return 'OK'
if __name__ == '__main__':
socketio.run(app)
Функцията send_n(n)
просто изпраща n
събития към клиента на разстояние 0,25 s.
Това е опростен Console
компонент (той възпроизвежда нежеланото поведение):
import { useState, useEffect } from 'react'
import '../styles/console.css'
import { Socket } from 'socket.io-client'
interface ConsoleProps {
socket: Socket
}
export default function Console(props: ConsoleProps) {
const [messages, setMessages] = useState<string[]>([])
useEffect(() => {
props.socket.on('console', msg => {
setMessages([...messages, `${new Date().toLocaleTimeString()} ${msg}`])
})
})
return (
<div className='console' style={{ height: '200px' }}>
<ul>
{messages.map((msg, i) => <li key={i}>{msg}</li>)}
</ul>
</div>
)
}
Той получава вече свързания сокет чрез подпори.
Компонентът се изобразява добре, докато има ~10 елемента, но след това се забавя и до 13-ия ред замръзва и дори не мога да затворя раздела, без да се налага първо да убия процеса.
Дебъгерът на Flask регистрира съобщението за всеки изобразен ред, но неизобразените редове (опитах с 25 като стойност за n
) изглежда никога не са били изпращани.
Така че имам 2 въпроса:
- Защо flask не изпраща всяко съобщение? Някаква лоша опашка?
- Защо реакцията замръзва, когато задният сокет замръзва?
Освен това, ако направя msg
клеймо за време, първите съобщения се изобразяват бързо, но разликата между клеймото за време и времево клеймо на React нараства много бързо с броя на съобщенията.