LINUX.ORG.RU

Проблема с socketio flask

 , , , ,


1

1

В общем что я хочу сделать — есть функция, которая работает медленно (парсит некоторые данные в интернете и отдаёт их постепенно, допустим с yield). Я хочу, чтобы пользователь не ждал всех результатов и потом увидел всю страницу целиком, а получал эти данные по мере поступления. Выбор пал на flask_socketio. Для примера я создал простейшее приложение. Оно отдаёт изначально готовый шаблон и этот шаблон я хочу наполнить новыми элементами. Код:

from flask import Flask, render_template
from flask_socketio import SocketIO
from time import sleep
app = Flask(__name__)
socketio = SocketIO(app)


@app.route('/')
def index():
    return render_template('index.html')


@socketio.on('connect')
def test_connect():
    for i in range(5):
        html = render_template('div.html', number=i)
        socketio.emit('update', {'tag': html})
        sleep(1)


if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', debug=True)
и 2 шаблона html, думаю их показывать не стоит, покажу только js из index.html:
	var insertElement = function(html){
		var el = document.createElement('div');
		el.innerHTML = html;
		return el.childNodes[0];
	}
	$(document).ready(function(){
		var socket = io.connect('http://' + document.domain + ':' + location.port);
		socket.on('update', function(response){
			insertElement(response.tag);
			console.log('data: ' + response.tag);
		});
	});
Версии используемых либ:

jquery — 3.1.1, socket.io — 1.7.2.

Собственно, что происходит: при загрузке страницы в консоли js я вижу очень долгий первый запрос, потом быстро несколько запросов и вывод в консоль в одну секунду всех результатов. Почему так происходит — я понять не могу, равно как и почему элементы, которые я создаю не появляются в DOM. Вот скрин происходящего click!.

Заранее благодарю за ответы/советы.

P.S. если я выбрал не тот подход, вполне соглашусь на подобный. Главное, чтобы при загрузке страницы не тупило, пока подготовятся все данные.

Почему так происходит — я понять не могу

Потому, что твой test_connect не асинхронный, а sleep в нём — и подавно. Твой flask_socketio не может ничего сделать до того, как test_connect завершится.

x3al ★★★★★ ()

P.S. если я выбрал не тот подход, вполне соглашусь на подобный. Главное, чтобы при загрузке страницы не тупило, пока подготовятся все данные.

Для начала определиться, какую модель конкуррентности ты хочешь. В простейшем случае ты можешь тупо потоково писать json (или ещё что) и, например, потоково парсить его на клиенте через тот же oboejs без всяких вебсокетов, если тебя устроят треды (или gevent).

Если не устраивают — думать.

PS: socketio сильно давно мёртв, сейчас давно пользуют просто websocket.

x3al ★★★★★ ()
Ответ на: комментарий от x3al

Чо это он мертв, он же всего лишь прослойка совместимости над теми же веб-сокетами или лонг-поллингом если клиент со старым IE пришел. Вроде коммитят чего-то, норм всё.

Кроме SocketIO.sleep ещё понадобится http://flask-socketio.readthedocs.io/en/latest/#flask_socketio.SocketIO.start....

Для flask'а это наверное самый простой вариант.

Btw, ТСу стоит ещё прочитать секцию Requirements в документации и убедиться что ему понятно всё что там написано.

Но вообще flask для проекта с websocket'ами не лучший выбор. В этом смысле кажется что aiohttp сейчас самый удобный.

ei-grad ★★★★★ ()
Ответ на: комментарий от ei-grad

со старым IE

1. Настолько старый IE (<=9) мёртв.

2. socketio — очень жирная абстракция, если настолько нужен IE — есть более легковесные и менее забагованные полифиллы.

x3al ★★★★★ ()