diff options
Diffstat (limited to 'src/site.clj')
| -rw-r--r-- | src/site.clj | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/src/site.clj b/src/site.clj index f2e5626..cce5da1 100644 --- a/src/site.clj +++ b/src/site.clj @@ -8,9 +8,30 @@ (defstruct user-struct :nick :last-seen) (defstruct message-struct :nick :content :timestamp) + (def users (ref {})) (def messages (ref [])) +(def run-flusher true) +(def flusher-sleep-ms 4000) +(def user-timeout-ms 30000) + +(defn swap [f] + (fn [& more] (apply f (reverse more)))) + +(def flusher (agent nil)) + +(defn flush! [x] + (when run-flusher + (send-off *agent* #'flush!)) + (dosync + (let [now (System/currentTimeMillis) + alive? (fn [[n u]] (> (u :last-seen) (- now user-timeout-ms)))] + (ref-set users + (into {} (filter alive? @users))))) + (. Thread (sleep flusher-sleep-ms)) + x) + (defn resp-error [message] {:status 400 :headers {} :body message}) @@ -19,14 +40,14 @@ (defn join-success [nick] (alter users assoc nick (struct user-struct nick (System/currentTimeMillis))) - (let [users (keys @users) - messages (take 20 @messages) + (let [users (sort (keys @users)) + messages (reverse (take 40 @messages)) data {"users" users "messages" messages}] [(session-assoc :nick nick) (resp-success data)])) (defn try-join [params] - (let [nick (params :nick)] + (let [nick (escape-html (params :nick))] (dosync (if (contains? @users nick) (resp-error "NICK_TAKEN") @@ -37,17 +58,18 @@ (defn refresh [nick] (dosync - (let [last-seen (get-in @users [nick :last-seen])] - (alter users assoc-in [nick :last-seen] (System/currentTimeMillis)) - (resp-success {"messages" (new-messages last-seen)})))) - -(defn swap [f] - (fn [& more] (apply f (reverse more)))) + (if (contains? @users nick) + (let [last-seen (get-in @users [nick :last-seen]) + user-list (sort (keys @users))] + (alter users assoc-in [nick :last-seen] (System/currentTimeMillis)) + (resp-success {"messages" (new-messages last-seen) + "users" user-list})) + (resp-error "UNKNOWN_USER")))) (defn msg [session params] (dosync (let [nick (session :nick) - content (params :content) + content (escape-html (params :content)) msg (struct message-struct nick content (System/currentTimeMillis))] (if (contains? @users nick) (do (alter messages (swap cons) msg) @@ -70,3 +92,4 @@ (run-server {:port 8080} "/*" (servlet pichat)) +(send-off flusher flush!)
\ No newline at end of file |
