server.clj 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. (ns bombnet.server
  2. (:require [com.stuartsierra.component :as component]
  3. [compojure.core :refer :all]
  4. [compojure.route :as route]
  5. [clojure.data.json :as json]
  6. [clojure.core.async :refer [>! >!! <! <!! alts! alts!! chan go go-loop timeout]]
  7. [org.httpkit.server :refer :all]
  8. [bombnet.manager :refer :all]))
  9. (defroutes app
  10. (GET "/" [] (ring.util.response/resource-response "index.html" {:root "public"}))
  11. (GET "/ws/:room" [room]
  12. (fn [request]
  13. (with-channel request channel
  14. (let [manager (get request ::manager)
  15. id (get request :query-string)
  16. in-ch (get-room manager room)
  17. out-ch (chan)]
  18. (>!! in-ch [:client-join {:id id :channel out-ch}])
  19. (go-loop []
  20. (send! channel (json/write-str (<! out-ch)))
  21. (recur))
  22. (on-close channel (fn [status] (>!! in-ch [:client-leave id])))
  23. (on-receive channel (fn [data]
  24. (let [parsed (json/read-str data :key-fn keyword)]
  25. (>!! in-ch [:message {:id id :message parsed}]))))))))
  26. (route/resources "/")
  27. (route/not-found "Not Found"))
  28. (defn wrap-manager
  29. [handler manager]
  30. (fn [req]
  31. (handler (assoc req ::manager manager))))
  32. (defrecord GameServer [server manager]
  33. component/Lifecycle
  34. (start [component]
  35. (if server
  36. component
  37. (let [handler (-> app
  38. (wrap-manager manager))]
  39. (println "Starting server")
  40. (assoc component :server (run-server handler {:port 8080})))))
  41. (stop [component]
  42. (if (not server)
  43. component
  44. (do
  45. (println "Stopping server")
  46. (server :timeout 100)
  47. (assoc component :server nil)))))
  48. (defn new-server []
  49. (component/using
  50. (map->GameServer {})
  51. [:manager]))