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 相关,并且在切换到 Gevent
和 python-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()
我有一个程序,后端用 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 相关,并且在切换到 Gevent
和 python-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()