miguelgrinberg / Flask-SocketIO

Socket.IO integration for Flask applications.
MIT License
5.31k stars 888 forks source link

why sleep or eventlet.monkey_patch() for SocketIO.emit? #1926

Closed byew closed 1 year ago

byew commented 1 year ago

Describe the question I am trying to complete a python backend server so that it could send messages to the front webpage when I receive data from Kafka. I found that when I use time.sleep(1) or don't use socketio.sleep(1) or use eventlet.monkey_patch()+socketio.sleep(1) , the backend cannot use socketio.emit to send messages to the frontend webpage.. But when I use socketio.sleep(1) or use eventlet.monkey_patch() or use eventlet.monkey_patch()+time.sleep(1) , the program runs fine. I don't know why this happens, so I want to ask everyone what the reason is? Below is my code:

import time
from flask import Flask, render_template
from flask_socketio import SocketIO
from flask_socketio import emit, send
from threading import Lock
import threading
from flask_cors import CORS
from kafka import KafkaConsumer
import json
#improt eventlet
#eventlet.monkey_patch()
app = Flask(__name__, template_folder='templates')
app.config['SECRET_KEY'] = 'secret!'
CORS(app, resources=r'/*')
socketio = SocketIO(app)
thread = None
thread_lock = Lock()
# print(socketio.async_mode)#### eventlet 

@app.route('/')
def index():
    print("hello world")
    return render_template('index1.html', async_mode=socketio.async_mode)

@socketio.on('message')
def handle_message(message):
    send(message)

def background_thread():
    consumer = KafkaConsumer(
                'test',
                consumer_timeout_ms=1 * 1000
                )
    # while True:
    for msg in consumer:
        data = json.loads(msg.value.decode('utf8'))
        print(data)
        socketio.emit("test", data)
        socketio.sleep(1)
    print("kafka timeout")

@socketio.on('connect')
def test_connect():
    print("socket io connect")
    # background_thread()
    global thread
    with thread_lock:
        if thread is None:
            thread = socketio.start_background_task(target=background_thread)

@socketio.on('disconnect', namespace='/test')
def test_disconnect():
    print('Client disconnected')

@socketio.on('my event')
def handle_my_custom_event(json):
    print('received json: ' + str(json))

if __name__ == '__main__':
    # socketio.run(app, debug=True)
    socketio.run(app, debug=True, host='0.0.0.0',port=5555)
miguelgrinberg commented 1 year ago

Please don't write issues when you have questions. I'd appreciate it if you follow the instructions and use the discussions board for questions. Thank you.

Regarding your question, I suggest you become familiar with how concurrency works in eventlet.

byew commented 1 year ago

ok,thank you!