【问题标题】:Use socket.io to display realtime data使用 socket.io 显示实时数据
【发布时间】:2016-10-23 22:42:54
【问题描述】:

我有一个 .csv 文件。 csv 文件中的每一行都包含文本和日期字段(也按日期排序)。通过迭代csv文件,我们统计每个日期的词频,并将词频发送到客户端,并使用html显示出来。

我正在使用 Python3、Flask 和 Flask-SocketIO,但是只显示最后日期的词频。调试信息可见Pastebin LINK。从调试信息来看,SocketIO 似乎一直在发出事件,而没有在客户端接收任何数据,直到迭代结束。我想要的是在迭代期间发送和接收每个数据,这样我就可以在客户端实时更新词频。我在使用 SocketIO 时做错了吗?

感谢您的任何建议。

对于 JavaScript:

$(document).ready(function(){
    //connect to the socket server.
    var socket = io.connect('http://' + document.domain + ':' +     location.port + '/test');

    //receive details from server
    socket.on('connect', function() {
        socket.emit('my_event', {data: 'I\'m connected!'});
    });

    socket.on('new_count', function(msg) {
        console.log("Received count");
        //get data
        var tags = msg.data;
        console.log(tags[0].key);
        numbers_string = '';
        for (var i = 0; i < tags.length; i++){
            numbers_string = numbers_string + '<p>' + tags[i].key + ': ' +    tags[i].value + '</p>';
        }
        $('#vis').html(numbers_string);
        socket.emit("my_event", {data: "one update received!"});
    });
});

对于 Python 代码:

day=""
@socketio.on('connect', namespace="/test")
def test_connect():
    global day
    print("clinet connected")
    with open("static/sorted_examples.csv", 'r') as f:
        reader = csv.DictReader(f)
        day = ""
        words = []
        for row in reader:
            text = row['text']
            date_day = row['date_day']
            words += text.split()
            if date_day != day:
                day = date_day
                word_count = Counter(words).most_common(20)
                words[:] = []
                emit_data = [dict([("key", k), ("value", v)]) for k, v in word_count]
                socketio.emit('new_count', {"data": emit_data}, namespace='/test')

【问题讨论】:

  • 如果代码 Flask 将在短时间内在 CVS 中的每一行发出一条消息。在 JavaScript 方面,您正在更新每条消息的 HTML,覆盖以前的更新。因此,您只会看到最后一条消息的变化。

标签: python flask socket.io flask-socketio


【解决方案1】:

此答案假设您使用的是实现协作多任务的 eventlet 或 gevent。

emit() 调用是异步工作的,这意味着在 eventlet 或 gevent 下,如果您希望适当的后台线程立即处理它,则需要释放 CPU。

这实际上非常简单,只需在emit() 之后添加一个socketio.sleep(0)。如果您发现这对性能影响太大,您可以选择每隔一个循环迭代或更多次休眠。基本上你需要找到合适的平衡点。

【讨论】:

  • 谢谢!我发现将 scoketio.sleep() 放在 emit() 之前对我有用!不知道为什么,放在emit()之后就不行了。
猜你喜欢
  • 2023-03-26
  • 2018-12-06
  • 2018-03-12
  • 1970-01-01
  • 2015-12-19
  • 2018-02-20
  • 2018-04-18
  • 2019-11-10
  • 1970-01-01
相关资源
最近更新 更多