Created
January 20, 2014 21:22
-
-
Save viperscape/8529476 to your computer and use it in GitHub Desktop.
http-kit connection timeout handling, client tracking. ping-clients should probably be named differently. assumes traffic is json.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def clients (atom {})) | |
(defn remove-client [ch] (close ch)(swap! clients dissoc ch)) | |
(defn purge-clients! [] | |
(doseq [c @clients] | |
(if (> (- (.getTime (java.util.Date.)) (.getTime (:last-seen (val c)))) 60000) | |
(remove-client (key c))))) | |
(defn broadcast-clients [data] "pass map to be reconstructed as json" | |
(doall(map #(send! (key %) (json/write-str data)) @clients))) | |
(def ping-clients (future (loop [] | |
(Thread/sleep (* 1000 35)) | |
(broadcast-clients {:ping ""}) | |
(purge-clients!) | |
(recur) ))) | |
;(future-cancel ping-clients) | |
(defn handler [req] | |
(with-channel req ch | |
(if (websocket? ch) | |
(do | |
(println "client connect " ch) | |
(swap! clients conj (hash-map ch {:token nil,:last-seen (java.util.Date.)})) | |
(on-close ch (fn [status] (println "client disconnect " status) | |
(if (= :normal status) ;clean disconnect? | |
(do(println "removing client" ch)(swap! clients dissoc ch)) | |
;;note: delayed client removal may be unnecessary, depending on how mobile interacts while android GC rolls around | |
(do(println "delaying client removal")(swap! clients assoc-in [ch :last-seen] (java.util.Date.))) ))) | |
(on-receive ch (fn [data] | |
(println "receiving data " ch) | |
(let [rj (json/read-str data :key-fn keyword)] | |
(if (:echo rj) (send! ch (json/write-str {:echo (:echo rj)}))) | |
(if (:broadcast rj) (broadcast-clients rj)) | |
(if (:pong rj) (swap! clients assoc-in [ch :last-seen] (java.util.Date.))) | |
))) | |
)))) | |
(defroutes all-routes | |
(GET "/" [] #'handler)) | |
(run-server (site #'all-routes) {:port 8080}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment