a25fa80

Branches > main > a25fa80 > files

Move keepalive to a global registry

Grahp, 2026-08-22

Commit: a25fa80739c846cbfb443e1d5a63c7db025e878e
Parent: c88c7b3

2 changed files:

src/net/bowmap/protocol/keepalive.clj added (view file)

@@ -0,0 +1,29 @@+(ns net.bowmap.protocol.keepalive+  (:require+   [clojure.core.async :refer [<!! io-thread put! timeout]]+   [net.bowmap.protocol.client :as client]+   [net.bowmap.protocol.packet :as pk]+   [net.bowmap.protocol.packet.clientbound :as clientbound]))++; TODO this takes a snapshot of the clients value...+(defonce keepalive-clients (ref #{}))+(defonce running? (atom false))++(defn keep-alive! [client]+  (dosync+    (commute keepalive-clients conj client)))++(defn start-keep-alives! []+  (when-not @running?+    (reset! running? true)+    (io-thread+      (loop []+        (<!! (timeout 20000))+        (doseq [{::client/keys [clientbound-packets] :as client} @keepalive-clients]+          (put! clientbound-packets {::pk/id ::clientbound/keep-alive+                                     :id (rand-int Integer/MAX_VALUE)})+          (fn [result]+            (when-not result+              (dosync+                (commute keepalive-clients disj client)))))+        (recur)))))

src/net/bowmap/protocol/server.clj modified (view file)

@@ -3,7 +3,7 @@    [clojure.core.async :refer [<!! >!! alt!! chan io-thread put! timeout]]    [net.bowmap.protocol.client :as client]    [net.bowmap.protocol.handle :as handle]-   [net.bowmap.protocol.packet :as pk]+   [net.bowmap.protocol.keepalive :as keepalive]    [net.bowmap.protocol.packet.clientbound :as clientbound :refer [encode-packet!]]    [net.bowmap.protocol.packet.serverbound :refer [decode-packet!]]    [net.bowmap.protocol.state :as state]@@ -16,7 +16,6 @@   (io-thread     (let [client (client/client connection)           clientbound-packets (req! client ::client/clientbound-packets)-          keep-alive (chan)           {::connection/keys! [serverbound-frames clientbound-frames close-fn]} connection]       (try         (loop [client client]@@ -31,27 +30,20 @@                                     (doseq [fact facts]                                       (execute-effects! (mapv #(assoc % ::client/client client) (logic/handle-fact fact))))                                     (when keep-alive?-                                      (put! keep-alive true))+                                      (keepalive/keep-alive! client))                                     (recur client))))             clientbound-packets ([packet]                                  (if (some? packet)                                    (do (>!! clientbound-frames (encode-packet! packet (::state/connection-state client)))                                        (recur client))-                                   (throw (Exception. "Clientbound packets was closed idk why"))))-            keep-alive ([x]-                        (when x-                          (put! clientbound-packets {::pk/id ::clientbound/keep-alive-                                                     :id (rand-int Integer/MAX_VALUE)})-                          (io-thread-                            (<!! (timeout 20000))-                            (put! keep-alive true)))-                        (recur client))))+                                   (throw (Exception. "Clientbound packets was closed idk why"))))))         (finally           ; TODO Send player disconnected fact, and update the player list from that           (close-fn))))))  (defn start-server! [port]   (let [connections (mc/start-server! port)]+    (keepalive/start-keep-alives!)     (loop []       (when-let [connection (<!! connections)]         (handle-connection connection))