使用socket.io显示实时数据
Use socket.io to display realtime data
我有一个 .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')
此答案假定您使用的是 eventlet 或 gevent,它们实现了协作式多任务处理。
emit()
调用是异步工作的,这意味着在 eventlet 或 gevent 下,如果您希望适当的后台线程立即处理它,您需要释放 CPU。
而这个其实很简单,就是在emit()
后面加一个socketio.sleep(0)
就可以了。如果您发现这对性能影响太大,您可以选择每隔一个循环迭代或更多次就休眠一次。基本上你需要找到合适的平衡点。
我有一个 .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')
此答案假定您使用的是 eventlet 或 gevent,它们实现了协作式多任务处理。
emit()
调用是异步工作的,这意味着在 eventlet 或 gevent 下,如果您希望适当的后台线程立即处理它,您需要释放 CPU。
而这个其实很简单,就是在emit()
后面加一个socketio.sleep(0)
就可以了。如果您发现这对性能影响太大,您可以选择每隔一个循环迭代或更多次就休眠一次。基本上你需要找到合适的平衡点。