Async sleep() 在“connect”事件中不工作,但在自定义事件中工作

问题描述

我使用了flask-socketio来实现websocket。我使用了 eventlet/socketio sleep() 函数,它应该异步工作。这在我的自定义事件中有效,但是当它在 connect 事件下时,它不起作用。这是可重现的代码

后端代码

from flask import Flask
from flask_socketio import SocketIO,emit,send
from eventlet import sleep
app = Flask(__name__)
socketio = SocketIO(app)

@app.route('/socket',methods=['POST','GET'])
def socket():
    """Landing page."""
    return app.send_static_file('websocket_test.html')

@socketio.on('connect',namespace='/test')
def test_connect(auth):
    for i in range(10):
        emit('my_response',{'data': str(i)})
        ##This does not work asynchronously
        socketio.sleep(1)

@socketio.on('my_event',namespace='/test')
def test_message(message):
    emit('my_response',{'data': message['dataaa']})
    for i in range(10):
        # emit('my_response',{'data': str(i)})
        emit('my_response',{'data': message['dataaa']})
        ##But This work asynchronously
        socketio.sleep(1)

if __name__ == '__main__':
    socketio.run(app)

websocket_test.html:

<!DOCTYPE HTML>
<html>
<head>
    <title>Socket-Test</title>
    <script src="//code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="https://cdn.socket.io/3.1.3/socket.io.min.js" integrity="sha384-cPwlPLvBTa3sKAgddT6krw0cJat7egBga3DJepJyrLl4Q9/5WLra3rrnMcyTyOnh" crossorigin="anonymous"></script>

    <script type="text/javascript" charset="utf-8">
        $(document).ready(function() {

            namespace = '/test';
            var socket = io(namespace);

            socket.on('connect',function(msg) {
               console.log(socket.id);
               console.log("connected");
               console.log(msg);
                $('#log').append('<br>' + $('<div/>').text(msg).html());
            });

            socket.on('my_response',function(msg,cb) {
                $('#log').append('<br>' + $('<div/>').text('logs #' + msg.count + ': ' + msg.data).html());

            });

            socket.on('message',cb) {
                $('#log').append('<br>' + $('<div/>').text('logs #' + msg.count + ': ' + msg.data).html());

            });
                $('form#emit').submit(function(event) {
                socket.emit('my_event',{dataaa: $('#emit_data').val()});
                return false;
            });

            $('form#disconnect').submit(function(event) {
                socket.emit('disconnect_request');
                return false;
            });

        });
    </script>
</head>
<body style="background-color:white;">

    <h1 style="background-color:white;">Socket</h1>

    <form id="emit" method="POST" action='#'>
        <input type="text" name="emit_data" id="emit_data" placeholder="Message">
        <input type="submit" value="Send Message">
    </form>

    <form id="disconnect" method="POST" action="#">
        <input type="submit" value="disconnect Server">
    </form>
    <h2 style="background-color:white;">Logs</h2>
    <div id="log" ></div>
</body>
</html>

解决方法

connect 事件处理程序应该仅用于决定是接受还是拒绝客户端连接。它必须快速运行,因为在连接处理程序返回之前连接并未完全建立。

将您的逻辑移至普通事件,并仅将连接处理程序用于身份验证/授权目的。