Подтвердить что ты не робот

Правильный способ записи живых данных с помощью django и bokeh

У меня есть сюжет bokeh, встроенный в приложение django. Я создаю сюжет в представлении django и нажимаю сюжет на сервер bokeh, чтобы показать сюжет на моей веб-странице.

#view.py
def view_plot(request):
    f=figure()
    f.plot(#some data#)
    session = push_session(curdoc())
    context = {'script': autoload_server(f, session_id=session.id)}
    return render_to_response('plot.html', context=context)

Все работает неплохо. Теперь я хочу сделать живой сюжет, каждый раз, когда создается новый DB-Entry, сюжет должен быть обновлен. Я не уверен, что это лучший способ.

Хорошо ли использовать таймер на веб-странице для запроса данных?

Или есть способ нажать кнопку обновления на сервере так, чтобы каждый подключенный к клиенту клиент получил обновление графика?

Я был бы очень благодарен за каждый намек.

Большое спасибо.

4b9b3361

Ответ 1

В основном ваша проблема заключается в том, что браузеры используют шаблон запроса-ответа: они отправляют запрос и сразу же возвращают ответ. У вас есть два варианта: периодически опроса сервера или какой-либо системы уведомлений.

Уведомления могут быть длительным опросом, то есть клиент делает запрос, а сервер не отвечает до тех пор, пока не появятся данные или через веб-сайты или через серверные события HTML5.

Теперь дело в том, что эти системы уведомлений не слишком хорошо интегрируются с традиционным развертыванием Django, поскольку они приводят к открытому сокету и соответствующему зависанию потока. Поэтому, если ваш веб-сервер имеет 10 потоков Django, один браузер с 10 вкладками может связать все их.

В настоящее время ведется работа по его изменению, но в то же время, если у вас нет жесткого требования в реальном времени или большого количества клиентов, просто установите таймер и опробуйте каждые x секунд, где x зависит от того, какая латентность приемлема. В зависимости от того, как хранятся ваши данные, я бы, вероятно, поставил простой механизм, чтобы сервер не отправлял весь набор данных каждый раз, а только то, что новый или не переносимый код возврата.

Например, по первому запросу сервер может помещать в ответ метку времени или серийный номер, а затем клиент запрашивает любые изменения с момента времени/серийного номера.

Система уведомлений дает вам лучшую задержку с более низкими накладными расходами, но, вероятно, ее также будет сложнее развернуть, и, вероятно, она будет чрезмерной, если это всего лишь приложение для внутреннего использования. Даже с системой уведомлений вам нужно сделать тщательный протокол, чтобы не пропустить что-то.

Ответ 2

По моему мнению, хорошо использовать что-то вроде таймера сердечного ритма в вашем интерфейсе, который запускает выборку данных каждую секунду или около того. Особенно, если вы выполнили кэширование на бэкэнд.

Более сложная версия может использовать что-то вроде каналы django для обработки связи через веб-сокеты.

Я бы сказал, это зависит от зрелости проекта.

Ответ 3

Что-то вроде этого сработало для меня:

#views.py
from bokeh.plotting import figure, curdoc
from bokeh.client import pull_session

def my_line_chart(request):
    session = pull_session(url = "http://localhost:5006/myapp")
    bokeh_script=autoload_server(None,url = "http://localhost:5006/myapp", session_id= session.id)
    return render(request, u'line_charts.html', {u'the_script': bokeh_script})

Затем на сервере bokeh используйте source.stream()

    #myapp
    '''
    everything else here
    '''
    def update():
        new_data = qu() #qu is the newdata to be updated
        source.stream(new_data, rollover = 60)
        print(source.data) #if you want to see new data

    curdoc().add_root(p)
    curdoc().add_periodic_callback(update,10000)

затем запустите свой сервер bokeh и разрешите соединение с django, как

bokeh serve --allow-websocket-origin=127.0.0.1:8000 myapp.py #you can add app2.py too

Я использовал порт 8000, потому что это мой порт django и порт 5006 на views.py, потому что это мой порт торнадо.

Проверить класс columndatasource для более

Надеюсь, что это поможет.