I'm trying to make a simple script to push events from a python app to a client. I made a Console
React component, which uses SocketIO to receive the events, and I'm pushing the messages with Flask SocketIO.
This is my 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)
The function send_n(n)
simply pushes n
events to the client spaced 0.25s.
This is the simplified Console
component (it reproduces the undesired behavior):
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>
)
}
It receives the already connected socket via props.
The component renders fine until it has ~10 elements, but then it slows down and by the 13th line it freezes, and I can't even close the tab without having to kill the process first.
Flask's debugger registers the message for every line rendered, but the lines not rendered (I tried with 25 as value for n
) appear to have never been sent.
So I have 2 questions:
- Why is flask not sending every message? Some kind of bad queuing?
- Why does react freezes when the backend socket freezes?
Also, if I make msg
a timestamp, the first messages render quickly, but the difference between the backend timestamp and the React timestamp grows very quickly with the number of messages.