server.clj

Bowmap · bowmap.git · Tickets

Branches > main > a6f37e8 > 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.
   Returns a future that delivers when the server closes."
  [server]
  (future
    (loop []
      (when-some [connection (<!! server)]
        (handle-connection! connection)
        (recur)))))