server.clj
Branches > main > 12be7f8 > files / src / net / bowmap / server / runtime / server.clj
(ns net.bowmap.server.runtime.server
(:require
[clojure.core.async :refer [<!! chan io-thread put!]]
[net.bowmap.server.network.connection :as connection]
[net.bowmap.server.protocol.codec :as codec]
[net.bowmap.server.protocol.phase :as phase]
[net.bowmap.server.runtime.packets :as packets]))
(defn client-step
([_] {::phase/phase ::phase/handshaking})
([client in frame]
(case in
::connection/serverbound-frames
(packets/apply-packet client (codec/decode-frame client frame)))))
(defn handle-connection! [{::connection/keys! [serverbound-frames clientbound-frames]}]
(let [clientbound-packets (chan 1024)]
(io-thread
(loop [client-state (client-step nil)]
(when-some [frame (<!! serverbound-frames)]
(let [[client' packets] (client-step client-state ::connection/serverbound-frames frame)]
(doseq [packet packets]
(put! clientbound-packets packet))
(recur client')))))))
(defn run-server!
"Starts running the given server, where server is a channel of connections.
Blocks until the server closes."
[server]
(loop []
(when-some [connection (<!! server)]
(handle-connection! connection)
(recur))))