90 lines
3.5 KiB
Clojure
90 lines
3.5 KiB
Clojure
(ns figwheel.client.socket
|
|
(:require
|
|
[figwheel.client.utils :as utils]
|
|
[cljs.reader :refer [read-string]]))
|
|
|
|
(defn get-websocket-imp []
|
|
(cond
|
|
(utils/html-env?) (aget js/window "WebSocket")
|
|
(utils/node-env?) (try (js/require "ws")
|
|
(catch js/Error e
|
|
nil))
|
|
(utils/worker-env?) (aget js/self "WebSocket")
|
|
:else nil))
|
|
|
|
;; messages have the following formats
|
|
|
|
;; files-changed message
|
|
;; { :msg-name :files-changed
|
|
;; :files [{:file "/js/compiled/out/example/core.js",
|
|
;; :type :javascript,
|
|
;; :msg-name :file-changed,
|
|
;; :namespace "example.core" }] }
|
|
|
|
;; css-files-changed message
|
|
;; there should really only be one file in here at a time
|
|
;; { :msg-name :css-files-changed
|
|
;; :files [{:file "/css/example.css",
|
|
;; :type :css }] }
|
|
|
|
;; compile-failed message
|
|
;; { :msg-name :compile-failed
|
|
;; :exception-data {:cause { ... lots of exception info ... } }}
|
|
;; the exception data is nested raw info obtained for the compile time
|
|
;; exception
|
|
|
|
(defonce message-history-atom (atom (list)))
|
|
|
|
(defonce socket-atom (atom false))
|
|
|
|
(defn send!
|
|
"Send a end message to the server."
|
|
[msg]
|
|
(when @socket-atom
|
|
(.send @socket-atom (pr-str msg))))
|
|
|
|
(defn close! []
|
|
(set! (.-onclose @socket-atom) identity)
|
|
(.close @socket-atom))
|
|
|
|
(defn handle-incoming-message [msg]
|
|
(utils/debug-prn msg)
|
|
(and (map? msg)
|
|
(:msg-name msg)
|
|
;; don't forward pings
|
|
(not= (:msg-name msg) :ping)
|
|
(swap! message-history-atom
|
|
conj msg)))
|
|
|
|
(defn open [{:keys [retry-count retried-count websocket-url build-id] :as opts}]
|
|
(if-let [WebSocket (get-websocket-imp)]
|
|
(do
|
|
(utils/log :debug "Figwheel: trying to open cljs reload socket")
|
|
(let [url (str websocket-url (if build-id (str "/" build-id) ""))
|
|
socket (WebSocket. url)]
|
|
(set! (.-onmessage socket) (fn [msg-str]
|
|
(when-let [msg
|
|
(read-string (.-data msg-str))]
|
|
(#'handle-incoming-message msg))))
|
|
(set! (.-onopen socket) (fn [x]
|
|
(reset! socket-atom socket)
|
|
(when (utils/html-env?)
|
|
(.addEventListener js/window "beforeunload" close!))
|
|
(utils/log :debug "Figwheel: socket connection established")))
|
|
(set! (.-onclose socket) (fn [x]
|
|
(let [retried-count (or retried-count 0)]
|
|
(utils/debug-prn "Figwheel: socket closed or failed to open")
|
|
(when (> retry-count retried-count)
|
|
(js/setTimeout
|
|
(fn []
|
|
(open
|
|
(assoc opts :retried-count (inc retried-count))))
|
|
;; linear back off
|
|
(min 10000 (+ 2000 (* 500 retried-count))))))))
|
|
(set! (.-onerror socket) (fn [x] (utils/debug-prn "Figwheel: socket error ")))
|
|
socket))
|
|
(utils/log :debug
|
|
(if (utils/node-env?)
|
|
"Figwheel: Can't start Figwheel!! Please make sure ws is installed\n do -> 'npm install ws'"
|
|
"Figwheel: Can't start Figwheel!! This browser doesn't support WebSockets"))))
|