refactor, using cljx to share common server and client code
This commit is contained in:
parent
0a1ee1df25
commit
143939af61
15
project.clj
15
project.clj
|
@ -9,5 +9,16 @@
|
|||
[org.clojure/core.async "0.1.346.0-17112a-alpha"]
|
||||
[net.thegeez/clj-browserchannel-server "0.1.0"]]
|
||||
|
||||
:source-paths ["src/clj"]
|
||||
:resource-paths ["src/cljs"])
|
||||
:source-paths ["target/generated/src/clj" "src/clj"]
|
||||
:resource-paths ["target/generated/src/cljs" "src/cljs"]
|
||||
|
||||
:profiles {:dev {:plugins [[com.keminglabs/cljx "0.5.0"]]}}
|
||||
|
||||
:cljx {:builds [{:source-paths ["src/cljx"]
|
||||
:output-path "target/generated/src/clj"
|
||||
:rules :clj}
|
||||
{:source-paths ["src/cljx"]
|
||||
:output-path "target/generated/src/cljs"
|
||||
:rules :cljs}]}
|
||||
|
||||
:prep-tasks [["cljx" "once"]])
|
||||
|
|
|
@ -2,40 +2,14 @@
|
|||
(:refer-clojure :exclude [send])
|
||||
(:require [clojure.edn :as edn]
|
||||
[clojure.core.async :refer [chan pub sub <! put! go-loop]]
|
||||
[net.thegeez.browserchannel :as browserchannel]))
|
||||
[net.thegeez.browserchannel :as browserchannel]
|
||||
[clj-browserchannel-messaging.utils :refer [run-middleware get-handlers encode-message decode-message]]))
|
||||
|
||||
(defonce ^:private handler-middleware (atom nil))
|
||||
|
||||
(defonce incoming-messages (chan))
|
||||
(defonce incoming-messages-pub (pub incoming-messages :topic))
|
||||
|
||||
(defn- run-middleware [middleware final-handler & args]
|
||||
(let [wrap (fn [handler [f & more]]
|
||||
(if f
|
||||
(recur (f handler) more)
|
||||
handler))
|
||||
handler (wrap final-handler middleware)]
|
||||
(apply handler args)))
|
||||
|
||||
(defn encode-message
|
||||
"encodes a message made up of a topic and body into a format that can be sent
|
||||
via browserchannel to a client. topic should be a keyword, while body can be
|
||||
any Clojure data structure. returns nil if the message could not be encoded."
|
||||
[{:keys [topic body] :as msg}]
|
||||
(if-let [topic (if topic (name topic))]
|
||||
{"topic" topic
|
||||
"body" (pr-str body)}))
|
||||
|
||||
(defn decode-message
|
||||
"decodes a message received via browserchannel into a map composed of a
|
||||
topic and body. returns nil if the message could not be decoded."
|
||||
[msg]
|
||||
(let [topic (get msg "topic")
|
||||
body (get msg "body")]
|
||||
(if topic
|
||||
{:topic (keyword topic)
|
||||
:body (edn/read-string body)})))
|
||||
|
||||
(defn send
|
||||
"sends a browserchannel message to a client identified by the given
|
||||
browserchannel session id. topic should be a keyword, while body can be
|
||||
|
@ -110,9 +84,7 @@
|
|||
(this differs from net.thegeez.browserchannel/wrap-browserchannel).
|
||||
|
||||
In addition, you can pass event handler functions. Note that the return
|
||||
value for all of these handlers is not used.
|
||||
|
||||
"
|
||||
value for all of these handlers is not used."
|
||||
[handler & [opts]]
|
||||
(-> handler
|
||||
(browserchannel/wrap-browserchannel
|
||||
|
@ -123,9 +95,6 @@
|
|||
(fn [browserchannel-session-id request]
|
||||
(handle-session browserchannel-session-id request))))))
|
||||
|
||||
(defn- get-handlers [middleware k]
|
||||
(->> middleware (map k) (remove nil?) (doall)))
|
||||
|
||||
(defn init!
|
||||
"Sets up browserchannel for server-side use. This function should be called
|
||||
once during application startup.
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
[cljs.reader :as reader]
|
||||
[cljs.core.async :refer [pub sub chan <! put!]]
|
||||
goog.net.BrowserChannel
|
||||
[goog.events :as events]))
|
||||
[goog.events :as events]
|
||||
[clj-browserchannel-messaging.utils :refer [run-middleware get-handlers encode-message decode-message]]))
|
||||
|
||||
(defonce ^:private handler-middleware (atom nil))
|
||||
|
||||
|
@ -14,34 +15,6 @@
|
|||
(defonce incoming-messages-pub (pub incoming-messages :topic))
|
||||
(defonce outgoing-messages (chan))
|
||||
|
||||
(defn- run-middleware [middleware final-handler & args]
|
||||
(let [wrap (fn [handler [f & more]]
|
||||
(if f
|
||||
(recur (f handler) more)
|
||||
handler))
|
||||
handler (wrap final-handler middleware)]
|
||||
(apply handler args)))
|
||||
|
||||
(defn encode-message
|
||||
"encodes a message composed of a topic and body into a format that can be
|
||||
sent via browserchannel. topic should be a keyword while body can be
|
||||
anything. returns nil if the message could not be encoded."
|
||||
[{:keys [topic body] :as msg}]
|
||||
(if-let [topic (name topic)]
|
||||
(clj->js {"topic" topic
|
||||
"body" (pr-str body)})))
|
||||
|
||||
(defn decode-message
|
||||
"decodes a message received via browserchannel into a map composed of a
|
||||
topic and body. returns nil if the message could not be decoded."
|
||||
[msg]
|
||||
(let [msg (js->clj msg)
|
||||
topic (keyword (get msg "topic"))
|
||||
body (get msg "body")]
|
||||
(if topic
|
||||
{:topic topic
|
||||
:body (reader/read-string body)})))
|
||||
|
||||
(defn send
|
||||
"sends a browserchannel message to the server asynchronously."
|
||||
[topic body]
|
||||
|
@ -67,12 +40,12 @@
|
|||
(:on-send @handler-middleware)
|
||||
(fn [msg]
|
||||
(if-let [encoded (encode-message msg)]
|
||||
(.sendMap channel encoded)))
|
||||
(.sendMap channel (clj->js encoded))))
|
||||
msg)
|
||||
(recur))))
|
||||
|
||||
(defn- handle-incoming [channel msg]
|
||||
(when-let [decoded (decode-message msg)]
|
||||
(when-let [decoded (decode-message (js->clj msg))]
|
||||
(run-middleware
|
||||
(:on-receive @handler-middleware)
|
||||
(fn [msg]
|
||||
|
@ -129,9 +102,6 @@
|
|||
(if-let [logger (-> browser-channel .getChannelDebug .getLogger)]
|
||||
(.setLevel logger level)))
|
||||
|
||||
(defn- get-handlers [middleware k]
|
||||
(->> middleware (map k) (remove nil?) (doall)))
|
||||
|
||||
(defn- register-middleware! [middleware]
|
||||
(reset!
|
||||
handler-middleware
|
||||
|
|
42
src/cljx/clj_browserchannel_messaging/utils.cljx
Normal file
42
src/cljx/clj_browserchannel_messaging/utils.cljx
Normal file
|
@ -0,0 +1,42 @@
|
|||
(ns clj-browserchannel-messaging.utils
|
||||
(:require
|
||||
#+clj [clojure.edn :as edn]
|
||||
#+cljs [cljs.reader :as reader]))
|
||||
|
||||
#+clj
|
||||
(defn decode-edn [s]
|
||||
(edn/read-string s))
|
||||
|
||||
#+cljs
|
||||
(defn decode-edn [s]
|
||||
(reader/read-string s))
|
||||
|
||||
(defn encode-message
|
||||
"encodes a message made up of a topic and body into a format that can be sent
|
||||
via browserchannel. topic should be a keyword, while body can be
|
||||
any Clojure data structure. returns nil if the message could not be encoded."
|
||||
[{:keys [topic body] :as msg}]
|
||||
(if-let [topic (if topic (name topic))]
|
||||
{"topic" topic
|
||||
"body" (pr-str body)}))
|
||||
|
||||
(defn decode-message
|
||||
"decodes a message received via browserchannel into a map composed of a
|
||||
topic and body. returns nil if the message could not be decoded."
|
||||
[msg]
|
||||
(let [topic (get msg "topic")
|
||||
body (get msg "body")]
|
||||
(if topic
|
||||
{:topic (keyword topic)
|
||||
:body (decode-edn body)})))
|
||||
|
||||
(defn run-middleware [middleware final-handler & args]
|
||||
(let [wrap (fn [handler [f & more]]
|
||||
(if f
|
||||
(recur (f handler) more)
|
||||
handler))
|
||||
handler (wrap final-handler middleware)]
|
||||
(apply handler args)))
|
||||
|
||||
(defn get-handlers [middleware k]
|
||||
(->> middleware (map k) (remove nil?) (doall)))
|
Reference in a new issue