Skip to content

Instantly share code, notes, and snippets.

@viperscape
Created January 20, 2014 21:22
Show Gist options
  • Save viperscape/8529476 to your computer and use it in GitHub Desktop.
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.
(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