使用Django频道websocket在Bokeh图客户端中更新数据

时间:2019-02-12 21:18:04

标签: jquery django websocket bokeh

当通过Django Channels实现的websocket接收到新数据时,我正在尝试更新Django中的Bokeh图。目的是流式传输通过网络套接字接收的新数据,而无需刷新浏览器。

我的 django视图创建散景图是:

#in views.py
def sensor(request):
    plot = figure(title= 'title' ,
        x_axis_label= 'X-Axis',
        y_axis_label= 'Y-Axis',
        plot_width =900,
        plot_height =500

    source = ColumnDataSource(data=dict(x=[], y=[]))
    plot.line('x', 'y', source=source, legend= 'f(x)', line_width = 2)

    script, div = components(plot)

    return render(request,"sensor.html",{'div':div,'script':script})

websocket 关联的 JQuery 是以下内容(我收到的消息是JSON格式的文本):

//In a script tag in sensor.html
$(function() {
  var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
  var endpoint = ws_scheme + '://' + window.location.host + window.location.pathname
  var ws = new WebSocket(endpoint);

  ws.onopen = function(e) {
         console.log("open", e);
  };

  ws.onmessage = function(e) {
      console.log("message", e);
      var new_data = jQuery.parseJSON(e.data).data);

      // UPDATE BOKEH ColumnDataSource WITH new_data 

  };
});

我的问题是我不知道如何通过JQuery更新Bokeh ColumnDataSource。我发现最接近的是使用Bokeh CustomJS Callbacks,但是我看不到将它们与websocket onmessage事件连接以及访问通过该事件收集的数据的任何方法。

我尝试过的另一个选项是嵌入单独的Bokeh Server,但是我找不到使用Django Channels websocket更新图的方法。初始化绘图时,我还必须将数据从Django模型传递到Bokeh服务器,这很不方便。

我们将不胜感激。谢谢

1 个答案:

答案 0 :(得分:0)

据我所知,您几乎是第一个建议或询问此问题的人[1]。恐怕您目前没有一个好的答案。 Bokeh协议定义明确且隔离,因此原则上可以用于通过任何合适的渠道进行通信,但是目前唯一使用它的是:

  • 基于标准的基于Tornado的默认Bokeh服务器,该服务器创建和管理自己的Websocket连接

  • Jupyter扩展,使用Jupyter通讯发送消息。

要使用Django通道,将意味着在Django之上重新实现当前Tornado Bokeh服务器的部分(或全部)子集。它还可能需要更改BokehJS本身。无论如何,这绝对是不平凡的领域,也就是说,我估计至少要为已经对Bokeh内部构件有丰富经验的人工作几个星期。

我很乐意尝试讨论更多细节,尤其是与您的用例相关的细节。您可能简化了假设,可能使其他选择成为可能(例如,如果您只需要将数据推入到散景图中,并且不需要Bokeh服务器提供的双向同步,那么您可能会想到自己的简单协议)。但是对于public mailing list来说,这种迭代讨论比SO更好。

[1]最近,一个商业客户也询问了Channels,甚至可能寻求资助该功能的功能,但是我无法推测何时或实际上会发生这种情况。