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
|
||||
"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
|
||||
"Shuts down and destroys the current development system."
|
||||
|
|
|
@ -38,15 +38,23 @@
|
|||
(include-js "/js/grub.js")
|
||||
[:script {:type "text/javascript"} "goog.require(\"grub.core\")"]]))
|
||||
|
||||
(def prod-config
|
||||
(def prod-system
|
||||
{:index prod-index-page
|
||||
:db {:name "grub"}
|
||||
:port 3000})
|
||||
:db {:name "grub"
|
||||
:db nil
|
||||
:conn nil}
|
||||
:port 3000
|
||||
:stop-server nil
|
||||
:states nil})
|
||||
|
||||
(def dev-config
|
||||
(def dev-system
|
||||
{:index dev-index-page
|
||||
:db {:name "grub-dev"}
|
||||
:port 3000})
|
||||
:db {:name "grub-dev"
|
||||
:db nil
|
||||
:conn nil}
|
||||
:port 3000
|
||||
:stop-server nil
|
||||
:states nil})
|
||||
|
||||
(defn handle-websocket [handler states]
|
||||
(fn [{:keys [websocket?] :as request}]
|
||||
|
@ -71,14 +79,14 @@
|
|||
(handle-root index)
|
||||
(handle-websocket states)))
|
||||
|
||||
(defn start [current {:keys [port db] :as config}]
|
||||
(defn start [current {:keys [port db] :as system}]
|
||||
(let [to-db (chan)
|
||||
db (db/connect-and-handle-events to-db (:name 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)
|
||||
(assoc config
|
||||
:db (merge (:db config) db)
|
||||
(assoc system
|
||||
:db (merge (:db system) db)
|
||||
:stop-server stop-server
|
||||
:states states)))
|
||||
|
||||
|
@ -121,8 +129,8 @@
|
|||
(not= (count arguments) 1) (exit 1 (usage summary))
|
||||
errors (exit 1 (error-msg errors)))
|
||||
(case (first arguments)
|
||||
"development" (start (merge dev-config options))
|
||||
"dev" (start (merge dev-config options))
|
||||
"production" (start (merge prod-config options))
|
||||
"prod" (start (merge prod-config options))
|
||||
"development" (start (merge dev-system options))
|
||||
"dev" (start (merge dev-system options))
|
||||
"production" (start (merge prod-system options))
|
||||
"prod" (start (merge prod-system options))
|
||||
(exit 1 (usage summary)))))
|
||||
|
|
|
@ -1,17 +1,38 @@
|
|||
(ns grub.core
|
||||
(:require [grub.state :as state]
|
||||
[grub.websocket :as ws]
|
||||
[grub.websocket :as websocket]
|
||||
[grub.view.app :as view]
|
||||
[cljs.core.async :as a :refer [<! >! chan]])
|
||||
(: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)
|
||||
remote-states (chan)
|
||||
to-remote (chan)
|
||||
from-remote (chan)]
|
||||
(view/render-app state/empty-state remote-states local-states)
|
||||
(ws/connect-client! to-remote from-remote)
|
||||
(state/init-client from-remote to-remote local-states remote-states)))
|
||||
from-remote (chan)
|
||||
view-state (view/render-app state/empty-state remote-states local-states)
|
||||
ws (websocket/connect (:pending-msg system) to-remote from-remote)
|
||||
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)))})
|
||||
(go (loop [] (when-let [new-state (<! <remote)]
|
||||
(reset! state new-state)
|
||||
(recur))))))
|
||||
(recur))))
|
||||
state))
|
||||
|
|
|
@ -8,34 +8,37 @@
|
|||
[grub.macros :refer [log logs]]))
|
||||
|
||||
(def server-url (str "ws://" (.-host (.-location js/document))))
|
||||
(def pending-msg (atom nil))
|
||||
(def reader (t/reader :json))
|
||||
(def writer (t/writer :json))
|
||||
|
||||
(defn send-pending-msg [websocket]
|
||||
(defn send-pending-msg [websocket pending-msg]
|
||||
(when (and (.isOpen websocket)
|
||||
(not (nil? @pending-msg)))
|
||||
(.send websocket (t/write writer @pending-msg))
|
||||
(reset! pending-msg nil)))
|
||||
|
||||
(defn on-connected [websocket event]
|
||||
(defn on-connected [websocket pending-msg event]
|
||||
(log "Connected:" event)
|
||||
(send-pending-msg websocket))
|
||||
(send-pending-msg websocket pending-msg))
|
||||
|
||||
(defn read-msg [msg]
|
||||
(t/read reader (.-message msg)))
|
||||
|
||||
(defn connect-client! [in out]
|
||||
(let [handler (goog.events.EventHandler.)
|
||||
websocket (goog.net.WebSocket.)
|
||||
listen (fn [type fun] (.listen handler websocket type fun false))]
|
||||
(listen goog.net.WebSocket.EventType.OPENED (partial on-connected websocket))
|
||||
(defn connect [pending-msg in out]
|
||||
(let [ws (goog.net.WebSocket.)
|
||||
handler (goog.events.EventHandler.)
|
||||
listen (fn [type fun] (.listen handler ws type fun false))]
|
||||
(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.CLOSED #(log "Closed:" %))
|
||||
(listen goog.net.WebSocket.EventType.ERROR #(log "Error:" %))
|
||||
(go (loop []
|
||||
(when-let [msg (<! in)]
|
||||
(reset! pending-msg msg)
|
||||
(send-pending-msg websocket)
|
||||
(send-pending-msg ws pending-msg)
|
||||
(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.core.async.macros :refer [go]]))
|
||||
|
||||
(def empty-state sync/empty-state)
|
||||
|
||||
(defmulti handle-event (fn [event]
|
||||
#+cljs (logs (:type event))
|
||||
(:type event)))
|
||||
|
@ -98,4 +100,5 @@
|
|||
(a/put! >view new-state))))
|
||||
(a/pipe <view local-events)
|
||||
(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…
Reference in a new issue