Start client code like server side
This commit is contained in:
parent
73cf89f9d5
commit
64b1bb05a7
6 changed files with 71 additions and 35 deletions
|
@ -12,7 +12,7 @@
|
||||||
(defn start
|
(defn start
|
||||||
"Starts the current development system."
|
"Starts the current development system."
|
||||||
[]
|
[]
|
||||||
(alter-var-root #'system system/start system/dev-config))
|
(alter-var-root #'system system/start system/dev-system))
|
||||||
|
|
||||||
(defn stop
|
(defn stop
|
||||||
"Shuts down and destroys the current development system."
|
"Shuts down and destroys the current development system."
|
||||||
|
|
|
@ -38,15 +38,23 @@
|
||||||
(include-js "/js/grub.js")
|
(include-js "/js/grub.js")
|
||||||
[:script {:type "text/javascript"} "goog.require(\"grub.core\")"]]))
|
[:script {:type "text/javascript"} "goog.require(\"grub.core\")"]]))
|
||||||
|
|
||||||
(def prod-config
|
(def prod-system
|
||||||
{:index prod-index-page
|
{:index prod-index-page
|
||||||
:db {:name "grub"}
|
:db {:name "grub"
|
||||||
:port 3000})
|
:db nil
|
||||||
|
:conn nil}
|
||||||
|
:port 3000
|
||||||
|
:stop-server nil
|
||||||
|
:states nil})
|
||||||
|
|
||||||
(def dev-config
|
(def dev-system
|
||||||
{:index dev-index-page
|
{:index dev-index-page
|
||||||
:db {:name "grub-dev"}
|
:db {:name "grub-dev"
|
||||||
:port 3000})
|
:db nil
|
||||||
|
:conn nil}
|
||||||
|
:port 3000
|
||||||
|
:stop-server nil
|
||||||
|
:states nil})
|
||||||
|
|
||||||
(defn handle-websocket [handler states]
|
(defn handle-websocket [handler states]
|
||||||
(fn [{:keys [websocket?] :as request}]
|
(fn [{:keys [websocket?] :as request}]
|
||||||
|
@ -71,14 +79,14 @@
|
||||||
(handle-root index)
|
(handle-root index)
|
||||||
(handle-websocket states)))
|
(handle-websocket states)))
|
||||||
|
|
||||||
(defn start [current {:keys [port db] :as config}]
|
(defn start [current {:keys [port db] :as system}]
|
||||||
(let [to-db (chan)
|
(let [to-db (chan)
|
||||||
db (db/connect-and-handle-events to-db (:name db))
|
db (db/connect-and-handle-events to-db (:name db))
|
||||||
states (state/init-server to-db (db/get-current-state (:db db)))
|
states (state/init-server to-db (db/get-current-state (:db db)))
|
||||||
stop-server (httpkit/run-server (make-handler config states) {:port port})]
|
stop-server (httpkit/run-server (make-handler system states) {:port port})]
|
||||||
(println "Started server on localhost:" port)
|
(println "Started server on localhost:" port)
|
||||||
(assoc config
|
(assoc system
|
||||||
:db (merge (:db config) db)
|
:db (merge (:db system) db)
|
||||||
:stop-server stop-server
|
:stop-server stop-server
|
||||||
:states states)))
|
:states states)))
|
||||||
|
|
||||||
|
@ -121,8 +129,8 @@
|
||||||
(not= (count arguments) 1) (exit 1 (usage summary))
|
(not= (count arguments) 1) (exit 1 (usage summary))
|
||||||
errors (exit 1 (error-msg errors)))
|
errors (exit 1 (error-msg errors)))
|
||||||
(case (first arguments)
|
(case (first arguments)
|
||||||
"development" (start (merge dev-config options))
|
"development" (start (merge dev-system options))
|
||||||
"dev" (start (merge dev-config options))
|
"dev" (start (merge dev-system options))
|
||||||
"production" (start (merge prod-config options))
|
"production" (start (merge prod-system options))
|
||||||
"prod" (start (merge prod-config options))
|
"prod" (start (merge prod-system options))
|
||||||
(exit 1 (usage summary)))))
|
(exit 1 (usage summary)))))
|
||||||
|
|
|
@ -1,17 +1,38 @@
|
||||||
(ns grub.core
|
(ns grub.core
|
||||||
(:require [grub.state :as state]
|
(:require [grub.state :as state]
|
||||||
[grub.websocket :as ws]
|
[grub.websocket :as websocket]
|
||||||
[grub.view.app :as view]
|
[grub.view.app :as view]
|
||||||
[cljs.core.async :as a :refer [<! >! chan]])
|
[cljs.core.async :as a :refer [<! >! chan]])
|
||||||
(:require-macros [grub.macros :refer [log logs]]))
|
(:require-macros [grub.macros :refer [log logs]]))
|
||||||
|
|
||||||
(defn init-app []
|
(def system
|
||||||
|
{:pending-msg (atom nil)
|
||||||
|
:ws (atom nil)
|
||||||
|
:channels {:local-states (chan)
|
||||||
|
:remote-states (chan)
|
||||||
|
:to-remote (chan)
|
||||||
|
:from-remote (chan)}
|
||||||
|
:view-state nil})
|
||||||
|
|
||||||
|
(defn start [system]
|
||||||
(let [local-states (chan)
|
(let [local-states (chan)
|
||||||
remote-states (chan)
|
remote-states (chan)
|
||||||
to-remote (chan)
|
to-remote (chan)
|
||||||
from-remote (chan)]
|
from-remote (chan)
|
||||||
(view/render-app state/empty-state remote-states local-states)
|
view-state (view/render-app state/empty-state remote-states local-states)
|
||||||
(ws/connect-client! to-remote from-remote)
|
ws (websocket/connect (:pending-msg system) to-remote from-remote)
|
||||||
(state/init-client from-remote to-remote local-states remote-states)))
|
agent-states (state/init-client from-remote to-remote local-states remote-states)]
|
||||||
|
(assoc system
|
||||||
|
:ws ws
|
||||||
|
:channels {:local-states local-states
|
||||||
|
:remote-states remote-states
|
||||||
|
:to-remote to-remote
|
||||||
|
:from-remote from-remote}
|
||||||
|
:view-state view-state
|
||||||
|
:agent-states agent-states)))
|
||||||
|
|
||||||
(init-app)
|
(defn stop [{:keys [channels ws]} system]
|
||||||
|
(doseq [c (vals channels)] (a/close! c))
|
||||||
|
(websocket/disconnect ws))
|
||||||
|
|
||||||
|
(start system)
|
||||||
|
|
|
@ -40,4 +40,5 @@
|
||||||
(when (= tag :local) (put! >remote new-state)))})
|
(when (= tag :local) (put! >remote new-state)))})
|
||||||
(go (loop [] (when-let [new-state (<! <remote)]
|
(go (loop [] (when-let [new-state (<! <remote)]
|
||||||
(reset! state new-state)
|
(reset! state new-state)
|
||||||
(recur))))))
|
(recur))))
|
||||||
|
state))
|
||||||
|
|
|
@ -8,34 +8,37 @@
|
||||||
[grub.macros :refer [log logs]]))
|
[grub.macros :refer [log logs]]))
|
||||||
|
|
||||||
(def server-url (str "ws://" (.-host (.-location js/document))))
|
(def server-url (str "ws://" (.-host (.-location js/document))))
|
||||||
(def pending-msg (atom nil))
|
|
||||||
(def reader (t/reader :json))
|
(def reader (t/reader :json))
|
||||||
(def writer (t/writer :json))
|
(def writer (t/writer :json))
|
||||||
|
|
||||||
(defn send-pending-msg [websocket]
|
(defn send-pending-msg [websocket pending-msg]
|
||||||
(when (and (.isOpen websocket)
|
(when (and (.isOpen websocket)
|
||||||
(not (nil? @pending-msg)))
|
(not (nil? @pending-msg)))
|
||||||
(.send websocket (t/write writer @pending-msg))
|
(.send websocket (t/write writer @pending-msg))
|
||||||
(reset! pending-msg nil)))
|
(reset! pending-msg nil)))
|
||||||
|
|
||||||
(defn on-connected [websocket event]
|
(defn on-connected [websocket pending-msg event]
|
||||||
(log "Connected:" event)
|
(log "Connected:" event)
|
||||||
(send-pending-msg websocket))
|
(send-pending-msg websocket pending-msg))
|
||||||
|
|
||||||
(defn read-msg [msg]
|
(defn read-msg [msg]
|
||||||
(t/read reader (.-message msg)))
|
(t/read reader (.-message msg)))
|
||||||
|
|
||||||
(defn connect-client! [in out]
|
(defn connect [pending-msg in out]
|
||||||
(let [handler (goog.events.EventHandler.)
|
(let [ws (goog.net.WebSocket.)
|
||||||
websocket (goog.net.WebSocket.)
|
handler (goog.events.EventHandler.)
|
||||||
listen (fn [type fun] (.listen handler websocket type fun false))]
|
listen (fn [type fun] (.listen handler ws type fun false))]
|
||||||
(listen goog.net.WebSocket.EventType.OPENED (partial on-connected websocket))
|
(listen goog.net.WebSocket.EventType.OPENED (partial on-connected ws pending-msg))
|
||||||
(listen goog.net.WebSocket.EventType.MESSAGE #(a/put! out (read-msg %)))
|
(listen goog.net.WebSocket.EventType.MESSAGE #(a/put! out (read-msg %)))
|
||||||
(listen goog.net.WebSocket.EventType.CLOSED #(log "Closed:" %))
|
(listen goog.net.WebSocket.EventType.CLOSED #(log "Closed:" %))
|
||||||
(listen goog.net.WebSocket.EventType.ERROR #(log "Error:" %))
|
(listen goog.net.WebSocket.EventType.ERROR #(log "Error:" %))
|
||||||
(go (loop []
|
(go (loop []
|
||||||
(when-let [msg (<! in)]
|
(when-let [msg (<! in)]
|
||||||
(reset! pending-msg msg)
|
(reset! pending-msg msg)
|
||||||
(send-pending-msg websocket)
|
(send-pending-msg ws pending-msg)
|
||||||
(recur))))
|
(recur))))
|
||||||
(.open websocket server-url)))
|
(.open ws server-url)
|
||||||
|
ws))
|
||||||
|
|
||||||
|
(defn disconnect [ws]
|
||||||
|
(.close ws))
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#+cljs (:require-macros [grub.macros :refer [log logs]]
|
#+cljs (:require-macros [grub.macros :refer [log logs]]
|
||||||
[cljs.core.async.macros :refer [go]]))
|
[cljs.core.async.macros :refer [go]]))
|
||||||
|
|
||||||
|
(def empty-state sync/empty-state)
|
||||||
|
|
||||||
(defmulti handle-event (fn [event]
|
(defmulti handle-event (fn [event]
|
||||||
#+cljs (logs (:type event))
|
#+cljs (logs (:type event))
|
||||||
(:type event)))
|
(:type event)))
|
||||||
|
@ -98,4 +100,5 @@
|
||||||
(a/put! >view new-state))))
|
(a/put! >view new-state))))
|
||||||
(a/pipe <view local-events)
|
(a/pipe <view local-events)
|
||||||
(make-client-agent (a/merge [local-events <remote]) >remote states)
|
(make-client-agent (a/merge [local-events <remote]) >remote states)
|
||||||
(a/put! >remote message/full-sync-request)))
|
(a/put! >remote message/full-sync-request)
|
||||||
|
states))
|
||||||
|
|
Loading…
Add table
Reference in a new issue