如何连接到我可以访问的远程服务器上运行的 REPL 会话,例如通过 SSH?
这对于网络专家来说可能是显而易见的,但我花了一段时间才发现,所以在这里记录下来。
在远程服务器上,启动 REPL 应用程序时,而不仅仅是
lein repl
强制绑定到端口:
lein repl :start :port 40000
在您的计算机上,以正常方式连接到远程服务器(例如通过 ssh)。然后以这种方式连接到您的应用程序:
lein repl :connect localhost:40000
就是这样!
我只是想总结一下上面的两个答案。它可以在我的机器上运行:
在远程机器上
lein repl :start :port 40000
在本地机器上
# SSH tunnel on one shell
ssh -NL 40000:localhost:40000 username@host
# Connect to the remote repl on another shell
lein repl :connect localhost:40000
嗯,这很简单。简而言之,有一些步骤需要完成:
nrepl
包应该是生产构建的一部分,而不仅仅是开发依赖项;现在详情:
1) 将这些 deps 添加到主
:dependencies
向量中:
:dependencies [[org.clojure/clojure "1.9.0"]
;; for remote debugging
[cider/cider-nrepl "0.17.0"]
[org.clojure/tools.nrepl "0.2.13"]
如果您使用 Emacs/Cider,则需要
cider-nrepl
。否则,您可以忽略它。
2)添加一个单独的命名空间来包装nrepl服务器:
(ns project.nrepl
(:require [clojure.tools.nrepl.server
:refer (start-server stop-server)]))
(defn nrepl-handler []
(require 'cider.nrepl)
(ns-resolve 'cider.nrepl 'cider-nrepl-handler))
(defonce __server (atom nil))
(def set-server! (partial reset! __server))
(def port 7888)
(defn start
[]
(when-not @__server
(set-server!
(start-server :port port :handler (nrepl-handler)))))
(defn stop
[]
(when-let [server @__server]
(stop-server server)
(set-server! nil)))
(defn init
[]
(start))
在您的核心模块中,只需调用
(project.nrepl/init)
。现在您的应用程序允许通过 nrepl 连接到它。
3)在远程服务器上,您可能会将 TCP 7888 端口暴露给外界,这是不安全的。至少应限制端口访问某些 IP 地址,例如你的办公室。更好的选择是通过 SSH 转发它,如下所示:
ssh -L 7888:<remote-host>:7888 <user>@<remote-host>
现在,打开 Emacs,调用
M-x cider-connect RET localhost 7888
就完成了:您已连接到远程应用程序。
顺便说一句,您可以轻松地从一个 REPL/clojure 应用程序连接到其他 REPL(例如比较 dev 和 UAT 之间的评估结果),如下所示
=> (require '[clojure.tools.nrepl :as repl])
nil
=> (with-open [conn (repl/connect :port 59258)]
(-> (repl/client conn 1000) ; message receive timeout required
(repl/message {:op "eval" :code "(+ 2 3)"})
repl/response-values))
[5]
更多信息请参见https://nrepl.org/nrepl/usage/clients.html#_talking_to_an_nrepl_endpoint_programmatically
连接到远程 clojure repl 的安全方式
$ clj "-J-Dclojure.server.repl={:port 5555 :accept clojure.core.server/repl}"
$ ssh -L :5555:localhost:5555 remoteuser@remotehost -p 22 -N -v
$ clj -Sdeps '{:deps {vlaaad/remote-repl {:mvn/version "1.1"}}}'
Downloading: vlaaad/remote-repl/1.1/remote-repl-1.1.pom from clojars
Downloading: vlaaad/remote-repl/1.1/remote-repl-1.1.jar from clojars
Clojure 1.10.1
user=> (require '[vlaaad.remote-repl :as rr])
user=> (rr/repl :port 5555)
clj -Sdeps '{:deps {vlaaad/remote-repl {:mvn/version "1.1"}}}' -m vlaaad.remote-repl :port 5555
也许是 ssh 隧道(如果 repl 作为 localhost:6666 在远程主机上运行)
在本地计算机上 ssh -L :6666:localhost:6666 Remoteuser@remotehost -N -v
然后只需连接到本地主机:6666