Skip to content

Instantly share code, notes, and snippets.

@rauhs
Created March 24, 2017 07:12
Show Gist options
  • Select an option

  • Save rauhs/1f7c93fd2af3179b505a329055d460a4 to your computer and use it in GitHub Desktop.

Select an option

Save rauhs/1f7c93fd2af3179b505a329055d460a4 to your computer and use it in GitHub Desktop.
(ns services.live-reload
(:require
[cheshire.core :as json]
[immutant.web :as immutant]
[immutant.web.async :as immut-async :refer [send! open?]]
[clojure.tools.logging :as log]
[mount.core :as mount]))
(defonce channels (atom #{}))
(defn- hello-message []
{:command "hello"
:protocols ["http://livereload.com/protocols/official-7"]
:serverName "clj-livereload"})
(defn reload!
"Given state and path, send reload message to the clients."
[path]
(doseq [channel @channels]
(if (open? channel)
(send! channel (json/generate-string {:command "reload"
:path path
:liveCSS true}))
(swap! channels disj channel))))
#_(reload! "/docs/hi")
(defn handle-request
[{:keys [uri] :as req}]
(case uri
"/livereload.js"
{:status 200
:headers {"Content-Type" "text/javascript;charset=UTF-8"}
:body (slurp "./third-party/livereload/livereload.js")}
"/livereload"
(immut-async/as-channel
req
{:on-open (fn [ch] (swap! channels conj ch))
:on-close (fn [ch _] (swap! channels disj ch))
:on-error (fn [ch throwable])
:on-message (fn [ch msg]
(let [parsed (json/decode msg true)]
(case (:command parsed)
"hello"
(send! ch (json/generate-string (hello-message)))
nil)))})))
(mount/defstate live-reload-server
:start (do
(reset! channels #{})
(log/info "Starting LiveReload server")
(immutant/run handle-request {:host "localhost"
:port 35729
:path "/"}))
:stop (do (immutant/stop live-reload-server)
(reset! channels #{})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment