Clojure - 如何远程连接到正在运行的 REPL 进程

17

如何连接到远程服务器上运行的REPL会话,例如通过SSH访问?

6个回答

20

对于网络专家来说这可能是显而易见的,但我花了一段时间才发现,所以在此记录下来。

在远程服务器上启动REPL应用程序时,不要仅使用lein repl,而是强制绑定到一个端口:

lein repl :start :port 40000

在您的计算机上,以正常方式连接到远程服务器(例如通过ssh)。 然后以以下方式连接到应用程序:

lein repl :connect localhost:40000

就是这样!


9
很简单,简要地说,需要完成以下几个步骤:
  1. nrepl包应该是生产版本的一部分,而不仅仅是开发时的依赖;
  2. 当你的应用程序启动时,它也会在特定端口上的一个单独线程中生成一个repl会话;
  3. 您的服务器会公开该端口,或者您可以通过SSH隧道来使用它。

现在详细说明:

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,就完成了:你已经连接到远程应用程序。

2
顺便提一下,nREPL 0.2.13 目前已经过时了。当前版本是0.4.5(它具有新的部署工件 nrepl/nrepl)。 - Bozhidar Batsov
好的,只是从旧项目中复制粘贴过来的。 - Ivan Grishaev

9
我来总结一下上面两个回答。这在我的电脑上可行:
在远程机器上:
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

谢谢 - 但是一旦创建了隧道,如何连接到端口40000以与repl交互呢? - alex314159

1

连接到远程Clojure REPL的安全方式

  1. 在远程机器上启动本地主机上的REPL
$ clj "-J-Dclojure.server.repl={:port 5555 :accept clojure.core.server/repl}"
  • 在本地机器上创建SSH隧道

  • $ ssh -L :5555:localhost:5555 remoteuser@remotehost -p 22 -N -v
    
    1. 在本地机器上启动repl并通过ssh连接到远程repl:
    $ clj -Sdeps '{:deps {vlaaad/remote-repl {:mvn/version "1.1"}}}'
    Downloading: vlaaad/remote-repl/1.1/remote-repl-1.1.pom from clojars <br>
    Downloading: vlaaad/remote-repl/1.1/remote-repl-1.1.jar from clojars <br>Clojure 1.10.1 <br>
    (require '[vlaaad.remote-repl :as rr])<br>
    user=> (rr/repl :port 5555)
    
    1. 或在本地机器上启动repl并立即进入远程repl
    clj -Sdeps '{:deps {vlaaad/remote-repl {:mvn/version "1.1"}}}' -m vlaaad.remote-repl :port 5555
    

    1

    顺便说一句,您可以轻松地从一个REPL / clojure应用程序连接到其他REPL(例如,比较开发和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


    0

    如果 repl 在远程主机上以 localhost:6666 运行,则可能需要使用 ssh 隧道。

    在本地机器上,使用 ssh -L :6666:localhost:6666 remoteuser@remotehost -N -v 命令进行连接。

    然后只需连接到 localhost:6666 即可。


    这对我没用 - 我打开了隧道,然后在本地机器上启动了一个单独的终端会话,输入了 nc localhost 6666,但什么也没有发生。 - alex314159
    你需要使用你的 repl 端口号。 - Alex Sarmanov

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接