【问题标题】:Problems connecting to a clojure nREPL with ring/compojure使用 ring/compojure 连接到 clojure nREPL 的问题
【发布时间】:2013-12-04 00:43:59
【问题描述】:

在 Java 1.7.0_21 Java HotSpot(TM) 64 位服务器虚拟机上运行 Leiningen 2.3.4

我无法连接到 nREPL 服务器。

我使用lein new luminus 设置了一个新项目,然后将依赖项添加到drawbridge ([com.cemerick/drawbridge "0.0.6"])。

我为 repl 添加了一个处理程序路由,如下所示(基于https://devcenter.heroku.com/articles/debugging-clojure):

(def drawbridge-handler
  (-> (cemerick.drawbridge/ring-handler)
      (wrap-keyword-params)
      (wrap-nested-params)
      (wrap-params)
      (wrap-session)))

(defn wrap-drawbridge [handler]
  (fn [req]
    (if (= "/repl" (:uri req))
      (drawbridge-handler req)
      (handler req))))

并将wrap-drawbridge 添加到我的中间件中。

然后我使用

启动服务器

lein ring server-headless

连接似乎运行良好,因为在 http:localhost:3000/repl 上执行 GET 请求会产生响应:["[\n","\n]"]

但我无法连接到 REPL:

> lein repl :connect 0.0.0.0:3000/repl
Connecting to nREPL at 0.0.0.0:3000/repl

然后,过了一段时间:

SocketException The transport's socket appears to have lost its connection to the nREPL server
    clojure.tools.nrepl.transport/bencode/fn--4287/fn--4288 (transport.clj:95)
    clojure.tools.nrepl.transport/bencode/fn--4287 (transport.clj:95)
    clojure.tools.nrepl.transport/fn-transport/fn--4261 (transport.clj:42)
    clojure.core/binding-conveyor-fn/fn--4107 (core.clj:1836)
    java.util.concurrent.FutureTask$Sync.innerRun (FutureTask.java:334)
    java.util.concurrent.FutureTask.run (FutureTask.java:166)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:615)
    java.lang.Thread.run (Thread.java:722)
Bye for now!

我错过了什么吗?

编辑:

在我的处理程序中添加了以下日志记录代码:

(defn wrap-drawbridge [handler]
  (fn [req]
    (if (= "/repl" (:uri req))
      (do (println "IN REPL ")
        (drawbridge-handler req))
      (handler req))))

按照建议与lein repl :connect http://localhost:3000/repl 连接时,我看到IN REPL 行在服务器控制台上以无限循环的形式打印。

【问题讨论】:

  • 有关吊桥服务器和客户端的最新示例,请查看nREPL over HTTP(s) with Drawbridge in 2020。在寻找 Drawbridge 时,这仍然是一个热门话题,因此最好将人们指向一个更新的代码示例 :-)

标签: clojure leiningen read-eval-print-loop nrepl


【解决方案1】:

不是一个直接的答案,但我发现我没有以正确的方式解决这个问题。

Luminus 创建一个project-name.repl 命名空间,应该用于交互式开发。

我发现我可以通过添加到我的project.clj 来做我想做的事

:repl-options {
                  :init-ns project-name.repl
                  :init (start-server)}

然后简单地使用lein repl 启动服务器。

比设置 nREPL 中间件简单得多!

【讨论】:

    【解决方案2】:

    您是否确定确实有请求进入您的服务器(例如通过打印)?

    但是,我的第一个猜测是 lein repl :connect 的行为会有所不同,具体取决于您传递的是 IP/端口对还是完全限定的 URL。由于drawbridge 似乎可以通过 HTTP 访问 nREPL,我建议您尝试一下:

    lein repl :connect http://localhost:3000/repl
    

    【讨论】:

    • 我添加了一些日志记录,它似乎确实可以连接,但几乎就像在无限循环中一样循环(参见我上面的编辑)。
    • 来自自述文件:Drawbridge is compatible with Clojure 1.2.0 - 1.4.0.。不确定这是否仍然有效,但它肯定表明应该使用的 nREPL drawbridge 版本与 Leiningen 中包含的客户端不完全兼容。那么,当您尝试使用旧版本的 Leiningen 连接到服务器时会发生什么?当你切换到 Clojure 1.4.0 时?
    • 这听起来像是一种损失。也许我这样做是错误的。有没有办法将 REPL 连接到正在运行的服务器(使用 ring/compojure)以进行实时调试?
    【解决方案3】:

    您需要在中间件列表的第一位添加wrap-drawbridge

    如果你这样做

    (def app (-> #'all-routes
                   wrap-drawbridge
                   ...
                   ...
                   ...
                   ))
    

    它就像一个魅力。

    【讨论】:

      猜你喜欢
      • 2015-03-15
      • 2013-06-12
      • 2013-07-18
      • 2015-05-08
      • 1970-01-01
      • 2014-11-25
      • 2011-04-21
      • 2014-05-11
      • 2015-04-28
      相关资源
      最近更新 更多