SocketIO 以突发而不是连续的方式传输数据

SocketIO transferring data in bursts rather than continuously

我有一个程序,后端用 Python 编写,前端用 React/Electron 编写,我使用 websockets,特别是 Socket.IO 在两者之间进行通信(我使用Flask-SocketIO 在后端)。

我想每秒连续传输几次少量数据(我的目标是每秒传输 10 次)但是在浏览器的接收端,数据以奇怪的方式突发:

data                        length      time
42["TRANSFER_DATA",250]     35          18:13:42.253
42["TRANSFER_DATA",253]     35          18:13:42.255
42["TRANSFER_DATA",259]     35          18:13:42.258
42["TRANSFER_DATA",265]     35          18:13:42.553
42["TRANSFER_DATA",270]     35          18:13:42.556
42["TRANSFER_DATA",276]     35          18:13:42.557
42["TRANSFER_DATA",281]     35          18:13:42.854
42["TRANSFER_DATA",287]     35          18:13:42.855
42["TRANSFER_DATA",292]     35          18:13:42.857
42["TRANSFER_DATA",298]     35          18:13:43.156
42["TRANSFER_DATA",303]     35          18:13:43.157
42["TRANSFER_DATA",309]     35          18:13:43.160

取自开发工具日志

您可以看到,它们不是连续进入(每 100 毫秒),而是每 300 毫秒进入 3 个突发。 我已经测试了它是否是后端冻结并且可以确认它不是,问题可能出在 Socket.IO 本身。

非常简化后端代码:

app = Flask(__name__)
sio = SocketIO(app, cors_allowed_origins="*")

def send_single(data, event_name, jsonify=False):
    if jsonify:
        data = json.dumps(data)
    sio.emit(event_name, data, json=jsonify)

def main_loop():
    while True: # This code is really simplified I don't actually do while True loops in the code itself
        data = get_this_data_from_somewhere()
        send_single(data, "TRANSFER_DATA")
        time.sleep(0.1)

if __name__ == '__main__':
    thread = threading.Thread(target=main_loop)
    thread.start()
    sio.run(app, host='127.0.0.1', port=58989)

非常简化前端代码:

import React, {Component} from 'react';
import io from 'socket.io-client'

const socketURL = "http://127.0.0.1:58989";

class App extends Component {
    state = {value: 0};
    async initSocket(){
        const socket = io(socketURL);
        this.setState({socket});
        await socket.on('connect', async () => {
            console.log("SocketIO connection established");
        });
    };

    setupListeners = () => {
        this.state.socket.on('TRANSFER_DATA', (data) => {
            this.setState({value: data});
        });
    };

    componentDidMount() {
        this.initSocket().then(this.setupListeners);
    }

    render() {
        return(
            <React.Fragment>
                <span>{this.state.value}</span>
            </React.Fragment>
        )
    }
}

export default App;

编辑: 我试图完全摆脱使用 Flask 来查看它是否与 Flask 相关,并且在切换到 Geventpython-socketio 之后问题仍然存在。

我还对 SocketIO 服务器进行了一些记录,它似乎以 100 毫秒的间隔正确发射

2019-12-10 21:15:15,710  INFO     emitting event "TRANSFER_DATA" to all [/]
2019-12-10 21:15:15,811  INFO     emitting event "TRANSFER_DATA" to all [/]
2019-12-10 21:15:15,911  INFO     emitting event "TRANSFER_DATA" to all [/]
2019-12-10 21:15:16,013  INFO     emitting event "TRANSFER_DATA" to all [/]
2019-12-10 21:15:16,114  INFO     emitting event "TRANSFER_DATA" to all [/]
2019-12-10 21:15:16,214  INFO     emitting event "TRANSFER_DATA" to all [/]
2019-12-10 21:15:16,315  INFO     emitting event "TRANSFER_DATA" to all [/]
2019-12-10 21:15:16,415  INFO     emitting event "TRANSFER_DATA" to all [/]
2019-12-10 21:15:16,516  INFO     emitting event "TRANSFER_DATA" to all [/]

感谢@Miguel 的回复,我意识到我忘记给标准库打补丁了,这似乎已经成功了!

from gevent import monkey
monkey.patch_all()