Я пытаюсь реализовать простое веб-приложение для отображения некоторых данных в режиме реального времени, используя Flask и график. js.
Ожидаемая работа выглядит следующим образом:
1) Клиент делает GET запрос с параметрами данных. например, http://127.0.0.1: 5000 / send? Patient = 'p1' & ecg = 301 API сохраняет данные в базе данных и возвращает данные, сохраненные в БД, в качестве ответа. (Я использовал sqlite3 в качестве БД)
2) В другой вкладке браузера, приведенный ниже URL-адрес доступен для отображения данных диаграммы. http://127.0.0.1: 5000 / На стороне сервера API chartData извлекает данные из БД и отправляет их клиенту. Он реализует события на стороне сервера, чтобы непрерывно отправлять значения клиенту. На стороне клиента браузер строит диаграмму для значений, полученных с сервера, используя plotly. js.
Оба API, как упомянуто выше, прекрасно работают при вызове по отдельности. Однако, если я позвоню http://127.0.0.1: 5000 / chartData и затем сделаю запрос GET из другой вкладки, броузер прекратит получать данные для диаграммы. Похоже, что запрос GET разрывает соединение для события на стороне сервера. Я уже использую аргумент 'threadaded = True' при запуске приложения flask.
Я новичок в Flask и веб-технологиях. Не могли бы вы помочь мне разобраться в проблеме здесь?
ОБНОВЛЕНИЕ: Наблюдаемые ниже вещи после много отладки:
1) Заменили db.fetchall () на фиктивный список, и на удивление это сработало. И / chartData, и / send API-запросы от клиентов работали гладко.
2) Добавлена попытка перехвата l oop внутри функции generateData. Таким образом, db.fetchall () возвращает объект-генератор всех записей указанной таблицы в БД sqlite. Поэтому, когда получен GET-запрос / send, исключение StoIteration вызывается методом generateData (). Это что-то странное, и я пока не могу понять причину.
Вот фрагмент кода:
app =Flask(__name__)
@app.route("/")
def main():
return render_template('myhtml.html')
@app.route("/chartData")
def getData():
def generateData():
db = ECG()
records = db.fetchall()
while True:
try:
data = records.next()
jsonData = json.dumps({'time': data[-1], 'value': data[2]})
print "data: {}\n\n".format(jsonData)
yield "data: {}\n\n".format(jsonData)
time.sleep(1)
except Exception as err:
logging.exception(err)
return Response(generateData(), mimetype='text/event-stream')
@app.route('/send', methods=['GET'])
def send():
try:
value = request.args.get('ecg')
patient = request.args.get('patient')
db = ECG()
logging.info("Arguments: {}".format((patient, value)))
logging.info("Updating DB")
if not db.addPatientReading(patient, value):
logging.error("Failed to update patients data")
data = list(db.fetchall())[-1]
logging.info("Data fetched from DB: {}".format(data))
return "DATA: {}".format(data)
except Exception as err:
logging.exception(err)
raise Exception("Failed to update data")
if __name__ == "__main__":
# app.run(debug=True)
logging.basicConfig(level=logging.DEBUG)
app.run(debug=True, threaded=True)