Clojure Oz/View!未连接到浏览器

Clojure Oz/View! Not Connecting to Browser

我正在尝试在 Clojure 中做一些(简单的)绘图,看起来 Oz 将是一个很好的长期解决方案。但是,我 运行 遇到了一些问题,只是试图将示例代码设为 运行。 PS 我对 ClojureScript / Reagent / Hiccup 完全陌生...

网站上显示了以下示例代码:

(defn play-data [& names]
  (for [n names
        i (range 20)]
    {:time i :item n :quantity (+ (Math/pow (* i (count n)) 0.8) (rand-int (count n)))}))

(def line-plot
  {:data {:values (play-data "monkey" "slipper" "broom")}
   :encoding {:x {:field "time" :type "quantitative"}
              :y {:field "quantity" :type "quantitative"}
              :color {:field "item" :type "nominal"}}
   :mark "line"})

;; Render the plot
(oz/view! line-plot)

对我来说,(oz/view! ...) 在我的浏览器中创建了一个空白页面,但实际上没有输出任何图。有人可以帮我弄清楚发生了什么事吗?我如何检查 Oz 是否直接连接到浏览器? Oz 是如何确定要使用哪个浏览器的(我目前使用的是 Brave)?

尝试类似下面的方法,它使用 my favorite template project.

(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require
    [oz.core :as oz]
    ))

(defn play-data [& names]
  (for [n names
        i (range 20)]
    {:time i :item n :quantity (+ (Math/pow (* i (count n)) 0.8) (rand-int (count n)))}))

(defn line-plot []
  {:data     {:values (play-data "monkey" "slipper" "broom")}
   :encoding {:x     {:field "time" :type "quantitative"}
              :y     {:field "quantity" :type "quantitative"}
              :color {:field "item" :type "nominal"}}
   :mark     "line"})

(dotest
  ; Render the plot
  (println \newline "calling (oz/start-server!)")
  (oz/start-server!) ; this is optional and is implied by oz/view!

  (println \newline "calling (oz/view! (line-plot))")
  (oz/view! (line-plot))

  (println \newline "sleeping")
  (Thread/sleep 5000)
)

结果:

 calling (oz/start-server!)
21-04-14 22:21:15 brandy INFO [oz.server:142] - Web server is running at `http://localhost:10666/`
Opening in existing browser session.
21-04-14 22:21:16 brandy INFO [oz.server:50] - Connected uids change: {:ws #{"b75d3026-919f-4927-a43c-ce678167348d"}, :ajax #{}, :any #{"b75d3026-919f-4927-a43c-ce678167348d"}}

 calling (oz/view! (line-plot))

 sleeping

您需要休眠几秒钟,读取输入,或者以其他方式保持线程活动。如果不是,线程似乎在信息从 JVM 传输到浏览器之前退出。

结果如下所示(使用 Chrome):

在内部,Oz 使用 clojure.java.browse, which internally uses java.awt.Desktop 打开默认浏览器。

Alan 似乎能够帮助您完成这项工作,但要澄清一点:

如果您 运行ning 作为脚本或程序(相对于连续 运行ning REPL 过程),您确实需要稍等片刻绘制消息以实际发送到前端(通过睡眠或其他方式)。

这种延迟可能是不可避免的,并且是使用 Sente 进行异步 websocket 通信的结果(尽管使用 any websocket lib 可能会有类似的问题)。对于 Sente,问题有点复杂,因为建立连接的方式有点奇怪,如果您不等到完全建立,第一条消息可能会丢失。最简单的方法就是等待几秒钟,但我正在考虑返回并尝试清理它,以便客户端在建立连接后立即发送消息,直到那个时候才会发送绘图消息收到消息。这可能会稍微减少等待时间,但对我来说只是低优先级。对于典型用法,第一个图是唯一需要一段时间才能加载的图;所有其他的都应该很快加载(除非它们特别大)。就像我说的,修复这个问题已经在我的雷达上,但如果您有灵感,请随时提交关于它的 GitHub 问题。

请注意,如果所有这些看起来很烦人,您也可以使用 Oz 的静态输出功能(oz/export!oz/compile)吐出一个 html 文件或静态图像。这将阻塞直到完成,因此在发送 websocket 消息之前程序停止不会有同样的问题。

关于 Oz 如何知道要打开哪个浏览器,JVM 知道默认浏览器设置,因此 Oz 可以使用它在您设置为默认的任何浏览器中打开。我遇到的唯一一次问题是从 Docker 中 运行ning 时,因为您通常无法从容器 运行 浏览器(即使您在那里重新 运行ning 你的代码,例如利用预烘焙的 python+clj 环境)。但这是一个非常小众的边缘案例,据我所知,除此之外它的效果还不错。

感谢试用 Oz!