Remove disconnected clients

This commit is contained in:
Nicholas Kariniemi 2013-10-09 09:04:51 +03:00
parent 955e853e93
commit 9669f57fbb

View file

@ -5,7 +5,7 @@
(def incoming-events (chan)) (def incoming-events (chan))
(def connected-clients (atom [])) (def connected-clients (atom {}))
(def ws-channel-id-count (atom 0)) (def ws-channel-id-count (atom 0))
@ -15,11 +15,18 @@
(defn add-connected-client! [ws-channel] (defn add-connected-client! [ws-channel]
(let [ws-channel-id (get-unique-ws-id) (let [ws-channel-id (get-unique-ws-id)
client-chan (chan)] client-chan (chan)]
(swap! connected-clients (swap! connected-clients #(assoc % ws-channel-id client-chan))
conj
{:id ws-channel-id :channel client-chan})
[ws-channel-id client-chan])) [ws-channel-id client-chan]))
(defn remove-connected-client! [status ws-channel ws-channel-id client-chan]
(println "Client disconnected:"
(.toString ws-channel)
(str "(" ws-channel-id ")")
"with status" status)
(swap! connected-clients #(dissoc % ws-channel-id))
(println (count @connected-clients) "client(s) still connected")
(a/close! client-chan))
(defn add-event-to-incoming-channel [raw-event ws-channel-id] (defn add-event-to-incoming-channel [raw-event ws-channel-id]
(let [parsed-event (read-string raw-event) (let [parsed-event (read-string raw-event)
@ -27,16 +34,12 @@
(println "Received event" event) (println "Received event" event)
(go (>! incoming-events event)))) (go (>! incoming-events event))))
(defn forward-client-events-to-others [ws-channel ws-channel-id]
(httpkit/on-receive ws-channel
#(add-event-to-incoming-channel % ws-channel-id)))
(defn forward-other-events-to-client [c ws-channel] (defn forward-other-events-to-client [c ws-channel]
(a/go-loop [] (let [event (<! c) (a/go-loop []
event-str (str event)] (when-let [event (<! c)]
(println "Send to client '" event-str "'") (println "Send to client '" (str event) "'")
(httpkit/send! ws-channel event-str)) (httpkit/send! ws-channel (str event))
(recur))) (recur))))
(defn send-current-grubs-and-recipes-to-client [client-chan] (defn send-current-grubs-and-recipes-to-client [client-chan]
@ -45,23 +48,26 @@
(defn setup-new-connection [ws-channel] (defn setup-new-connection [ws-channel]
(let [[ws-channel-id client-chan] (add-connected-client! ws-channel)] (let [[ws-channel-id client-chan] (add-connected-client! ws-channel)]
(println "Channel connected:" (.toString ws-channel)) (println "Client connected:" (.toString ws-channel) (str "(" ws-channel-id ")"))
(forward-client-events-to-others ws-channel ws-channel-id) (println (count @connected-clients) "client(s) connected")
(httpkit/on-close ws-channel #(remove-connected-client! % ws-channel ws-channel-id client-chan))
(httpkit/on-receive ws-channel #(add-event-to-incoming-channel % ws-channel-id))
(forward-other-events-to-client client-chan ws-channel) (forward-other-events-to-client client-chan ws-channel)
(send-current-grubs-and-recipes-to-client client-chan))) (send-current-grubs-and-recipes-to-client client-chan)))
(defn websocket-handler [request] (defn websocket-handler [request]
(httpkit/with-channel request ws-channel (setup-new-connection ws-channel))) (httpkit/with-channel request ws-channel (setup-new-connection ws-channel)))
(defn get-other-clients [my-ws-channel-id] (defn get-other-client-channels [my-ws-channel-id]
(filter #(not (= (:id %) my-ws-channel-id)) (-> @connected-clients
@connected-clients)) (dissoc my-ws-channel-id)
(vals)))
(defn push-event-to-others [orig-event] (defn push-event-to-others [orig-event]
(let [my-ws-channel-id (:ws-channel orig-event) (let [my-ws-channel-id (:ws-channel orig-event)
event (dissoc orig-event :ws-channel)] event (dissoc orig-event :ws-channel)]
(go (doseq [{ch :channel} (get-other-clients my-ws-channel-id)] (go (doseq [c (get-other-client-channels my-ws-channel-id)]
(>! ch event))))) (>! c event)))))
(defn pass-received-events-to-clients-and-db [db-chan] (defn pass-received-events-to-clients-and-db [db-chan]
(let [in' (a/mult incoming-events) (let [in' (a/mult incoming-events)