我有一个 ClojureScript 应用程序,我想对服务器进行 RPC 调用,这看起来像客户端上的普通函数 core.async 调用。
为了做到这一点,我基于 cljx 编写了下面的代码。在 RPC 定义部分,我必须添加我想作为 RPC 公开给客户端的所有服务器端函数。
有没有办法在没有样板代码的情况下做得更好?
考虑如何改进它,我唯一的想法是编写一个 leiningen 插件,它生成 RPC 所需的服务器端和客户端代码,即我目前使用 cljx 所做的部分。有没有更好的办法?
(ns myapp.shared.rpc
(:require
#+cljs [myapp.tools :refer [send log]]
#+cljs [cljs.reader :as reader]
#+clj [clojure.tools.logging :as log]
#+clj [noir.response :refer [edn]]
#+clj [myapp.rpc :as rpc]
))
#+cljs (defn rpc-client [function params]
#+cljs (log "RPC call: (" function params ")")
#+cljs (send "POST" "/api"
#+cljs (str "rpc=" (pr-str {:fun function :params params}))
#+cljs (fn [x]
#+cljs (log "RPC response:'" x "'")
#+cljs (:response (reader/read-string x)))))
#+clj (defmulti rpc-impl #(:fun %))
#+clj (defn rpc-server [{rpc :rpc}]
#+clj (log/info "RPC call received:" rpc)
#+clj (let [response (-> rpc read-string rpc-impl)]
#+clj (log/info "RPC response sent: '" response "'")
#+clj (edn {:response response})))
;;;;; RPC definitions
#+cljs (defn demo [ & p] (rpc-client :demo p))
#+clj (defmethod rpc-impl :demo [{p :params}] (apply rpc/demo p))