【问题标题】:react + socket.io emits not going through - basic errorreact + socket.io 发出未通过 - 基本错误
【发布时间】:2018-02-16 23:52:17
【问题描述】:

我对reactjs或者socket.io的理解肯定有一个简单的错误。我有一个服务器发送从 2 到 5 迭代的“速度”值,以及一个接收并显示它们的客户端。

问题:

预期行为:客户端每秒显示从 1 到 5 迭代的数字,并在 5 处停止。客户端记录它已收到 4 条具有更新速度值的消息(每秒一条新消息)

实际行为:客户端显示速度为1。客户端等待4秒。客户端显示速度为 5,并且在那一刻,记录从服务器接收到 4 条具有迭代速度的消息。

有什么问题?几乎就像服务器同时发送所有 4 条速度消息一样。

客户端代码:

import React from 'react';
import {CircleGauge} from 'react-launch-gauge';
import io from 'socket.io-client';

class App extends React.Component {
    constructor(props, context) {
        super(props, context)
        this.state = {
            speed: 1
        };
    }
    componentDidMount() {
        const socket = io('http://localhost:5000');
        socket.on('data update', data => 
            this.setState( { speed: data }, 
                () => console.log("got the speed: " + this.state.speed)));
        socket.open();
    }

    render() {
        return (
            <div>
                <p> The velocity received is: {this.state.speed}  </p>
            </div>
        );
    }
}
export default App;

服务器代码:

from flask import Flask, render_template
from flask_socketio import SocketIO, emit
import time

sendData = False;

app = Flask(__name__)
socketio = SocketIO(app)

@socketio.on('connect')
def dataSent():
    print('they connected**********************************')
    for i in range(2,6):
        socketio.emit('data update', i)
        time.sleep(1)
        print(i)


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

【问题讨论】:

  • 不确定服务器代码。您确定服务器在触发data update 消息之前等待建立连接吗?
  • 是的,socketio.on('connect') 绑定在客户端连接之前不会触发
  • 在客户端:尝试删除手册socket.open();并阻止轮询io('http://localhost:5000',{transports: ['websocket'], upgrade: false});

标签: python reactjs flask websocket socket.io


【解决方案1】:

当客户端通过websocket请求连接时

const socket = io(‘ws://localhost:5000’);

它必须等到首先建立连接,然后才能对消息执行任何操作。

时建立连接
@socketio.on(‘connect’)
def ...

完成了。所以看起来客户端等到所有的发射完成,然后开始对消息做出反应。

您可能需要使您的 for 循环异步,以便服务器在发出数据之前首先响应客户端有关连接的信息。例如,您可以将 for 循环分割成一个单独的函数并使用 flask 的后台任务:

@socketio.on(‘connect’)
def dataSent():
    print(‘...’)
    socketio.start_background_task(target=emitloop)

def emitloop():
    for i in range(2,6):
        socketio.emit(‘data update’, i)
        time.sleep(1)

(如果flask被配置为后台任务使用gevent,那么你需要安装gevent或flask的gevent插件。)

您也可以尝试使用基于函数的 setState(即将函数传递给 setState 而不是状态对象),因为 setState 是异步的,否则 react 可以将它们组合在一起。

【讨论】:

    猜你喜欢
    • 2012-03-23
    • 1970-01-01
    • 2017-02-27
    • 1970-01-01
    • 2021-05-30
    • 2021-08-28
    • 2020-09-21
    • 1970-01-01
    • 2023-03-13
    相关资源
    最近更新 更多