【问题标题】:Clojure - how to connect to running REPL process remotelyClojure - 如何远程连接到正在运行的 REPL 进程
【发布时间】:2019-02-26 19:18:50
【问题描述】:

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

【问题讨论】:

    标签: ssh clojure remote-access leiningen nrepl


    【解决方案1】:

    连接到远程 clojure repl 的安全方式

    1. 在远程机器上的 localhost 上启动 repl
    $ clj "-J-Dclojure.server.repl={:port 5555 :accept clojure.core.server/repl}"
    
    1. 在本地机器上创建 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
    

    【讨论】:

      【解决方案2】:

      顺便说一句,您可以像这样轻松地从一个 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

      【讨论】:

        【解决方案3】:

        嗯,这很简单。简而言之,有一些步骤需要完成:

        1. nrepl 包应该是生产构建的一部分,而不仅仅是开发依赖项;
        2. 当您的应用启动时,它还会在特定端口上的单独线程中生成一个 repl 会话;
        3. 您的服务器要么公开该端口,要么通过 SSH 将其隧道化。

        现在详细介绍:

        1) 将这些 dep 添加到主 :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 即可完成:您已连接到远程应用程序。

        【讨论】:

        • 顺便说一句,nREPL 0.2.13 在这一点上是古老的。当前版本是 0.4.5(它具有新的部署工件 nrepl/nrepl)。
        • 对,只是从旧项目中复制粘贴过来的。
        【解决方案4】:

        我只是想总结一下上面的两个答案。它适用于我的机器:

        在远程机器上

        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 交互?
        【解决方案5】:

        也许是 ssh 隧道(如果 repl 在远程主机上运行为 localhost:6666)

        在本地机器上 ssh -L :6666:localhost:6666 remoteuser@remotehost -N -v

        然后只需连接到 localhost:6666

        【讨论】:

        • 这对我不起作用 - 我打开了隧道,然后在本地机器上启动了一个单独的终端会话,输入 nc localhost 6666 并没有发生任何事情。
        • 你需要使用你的repl端口号
        【解决方案6】:

        这对网络专家来说可能很明显,但我花了一段时间才发现,所以在这里记录一下。

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

        lein repl :start :port 40000
        

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

        lein repl :connect localhost:40000
        

        就是这样!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-28
          • 1970-01-01
          • 2011-05-07
          相关资源
          最近更新 更多