diff --git a/src/elin/component/server.clj b/src/elin/component/server.clj index 4b4656db..a66106a0 100644 --- a/src/elin/component/server.clj +++ b/src/elin/component/server.clj @@ -1,21 +1,43 @@ (ns elin.component.server (:require + [clojure.core.async :as async] [com.stuartsierra.component :as component] [elin.component.server.nvim :as e.c.s.nvim] [elin.component.server.vim :as e.c.s.vim] - [elin.constant.host :as e.c.host]) + [elin.constant.host :as e.c.host] + [elin.protocol.rpc :as e.p.rpc]) (:import java.net.ServerSocket)) +(defn on-accept + [handler message] + (if (e.p.rpc/response? message) + (let [{:keys [response-manager]} message + {:keys [id error result]} (e.p.rpc/parse-message message)] + (when-let [ch (get @response-manager id)] + (swap! response-manager dissoc id) + (async/go (async/>! ch {:result result :error error})))) + (let [[res err] (when-not (e.p.rpc/response? message) + (try + (when (sequential? (:message message)) + [(handler message)]) + (catch Exception ex + [nil (ex-message ex)])))] + (when (e.p.rpc/request? message) + (e.p.rpc/response! message err res) + (.flush (:output-stream message)))))) + (defrecord Server [host port server-socket server] component/Lifecycle (start [this] (when-not server (let [server-sock (ServerSocket. port) + handler (:handler (:handler this)) server-arg {:host host :server-socket server-sock - :handler (:handler (:handler this))} + :on-accept (partial on-accept handler)} + ;; :handler handler} server (future (if (= e.c.host/nvim host) (e.c.s.nvim/start-server server-arg) diff --git a/src/elin/component/server/nvim.clj b/src/elin/component/server/nvim.clj index a4bbe82f..8a5589b5 100644 --- a/src/elin/component/server/nvim.clj +++ b/src/elin/component/server/nvim.clj @@ -75,43 +75,28 @@ (e.p.rpc/notify! this ["nvim_echo" [[[text highlight]] true {}]]))) (defn start-server - [{:keys [host server-socket handler]}] + [{:keys [host server-socket on-accept]}] (let [response-manager (atom {})] + ;; Client accepting loop (loop [] (try (with-open [client-sock (.accept server-socket)] (let [output-stream (.getOutputStream client-sock) data-input-stream (DataInputStream. (.getInputStream client-sock))] + ;; Client message reading loop (loop [] - (let [raw-msg (msg/unpack-stream data-input-stream) - _ (e.log/info "received" (pr-str raw-msg)) - msg (map->NvimMessage {:host host - :message raw-msg - :output-stream output-stream - :response-manager response-manager})] - (if (e.p.rpc/response? msg) - (let [{:keys [id error result]} (e.p.rpc/parse-message msg)] - (if error - ;; FIXME - nil - (when-let [ch (get @response-manager id)] - (swap! response-manager dissoc id) - (async/go (async/>! ch result)))) - (swap! response-manager dissoc id)) - (let [[res err] (try - (when (sequential? raw-msg) - [(handler msg)]) - (catch Exception ex - [nil (ex-message ex)]))] - (when (e.p.rpc/request? msg) - (e.p.rpc/response! msg err res) - (.flush output-stream))))) + (let [raw-msg (msg/unpack-stream data-input-stream)] + (e.log/debug "Neovim server received message:" (pr-str raw-msg)) + (on-accept (map->NvimMessage {:host host + :message raw-msg + :output-stream output-stream + :response-manager response-manager}))) (when-not (.isClosed client-sock) (recur)))) - (e.log/info "FIXME client-sock closed...")) + (e.log/debug "Client socket is closed")) (catch EOFException _ nil) (catch Exception ex - (println "closed client connection: " (ex-message ex)))) + (e.log/debug "Client connection is closed" (ex-message ex)))) (when-not (.isClosed server-socket) (recur))))) diff --git a/src/elin/component/server/vim.clj b/src/elin/component/server/vim.clj index 801ff154..9b45c416 100644 --- a/src/elin/component/server/vim.clj +++ b/src/elin/component/server/vim.clj @@ -31,6 +31,7 @@ (e.p.rpc/response? this) (let [[id result] message] {:id id + :error nil :result result}) (e.p.rpc/request? this) @@ -55,14 +56,17 @@ maybe-ch (when id (async/chan))] (when (and id maybe-ch) (swap! response-manager assoc id maybe-ch)) + (e.log/info "FIXME request!" (pr-str content)) (json/generate-stream content (io/writer output-stream)) maybe-ch)) (notify! [_ content] + (e.log/info "FIXME notify! " (pr-str content)) (json/generate-stream content (io/writer output-stream))) (response! [this error result] (when-let [id (:id (e.p.rpc/parse-message this))] + (e.log/info "FIXME" (pr-str [id (or error result)])) (-> [id (or error result)] (json/generate-stream (io/writer output-stream))))) @@ -79,41 +83,28 @@ (e.p.rpc/notify! this ["call" "elin#internal#rpc#echom" [text highlight]]))) (defn start-server - [{:keys [host server-socket handler]}] + [{:keys [host server-socket on-accept]}] (let [response-manager (atom {})] + ;; Client accepting loop (loop [] (try (with-open [client-sock (.accept server-socket)] (let [output-stream (.getOutputStream client-sock) input-stream (io/reader (.getInputStream client-sock))] + ;; Client message reading loop (loop [] - (let [raw-msg (json/parse-stream input-stream) - msg (map->VimMessage {:host host - :message raw-msg - :output-stream output-stream - :response-manager response-manager}) - _ (e.log/info "received" (pr-str raw-msg))] - (if (e.p.rpc/response? msg) - (let [{:keys [id result]} (e.p.rpc/parse-message msg)] - (when-let [ch (get @response-manager id)] - (swap! response-manager dissoc id) - (async/go (async/>! ch result)))) - (let [[res err] (when-not (e.p.rpc/response? msg) - (try - (when (sequential? raw-msg) - [(handler msg)]) - (catch Exception ex - [nil (ex-message ex)])))] - - (when (e.p.rpc/request? msg) - (e.p.rpc/response! msg err res) - (.flush output-stream))))) + (let [raw-msg (json/parse-stream input-stream)] + (e.log/debug "Vim server received message:" (pr-str raw-msg)) + (on-accept (map->VimMessage {:host host + :message raw-msg + :output-stream output-stream + :response-manager response-manager}))) (when-not (.isClosed client-sock) (recur)))) - (e.log/info "FIXME client-sock closed...")) + (e.log/debug "Client socket is closed")) (catch EOFException _ nil) (catch Exception ex - (println "closed client connection: " (ex-message ex)))) + (e.log/debug "Client connection is closed" (ex-message ex)))) (when-not (.isClosed server-socket) (recur)))))