51010ca
Branches > client-handling-rewrite > 51010ca > files
Remove special keepalive in message application and make generic process notion
Commit: 51010caa4bd0ad4ae2d524b69e4b0eecbe0cd5f7
Parent: 9f61bc1
2 changed files:
src/net/bowmap/message_application.clj view file
@@ -10,7 +10,20 @@ [net.bowmap.network.state :as state])) (S/def ::messages (s/coll-of ::msg/message :type vector?))-(S/def ::response (s/schema [::client/client ::messages ::keep-alive?])) ; And eventually game events as well :)+;; TODO def ::processes+(S/def ::response (s/schema [::client/client ::messages ::processes])) ; And eventually game events as well :)++(defmulti apply-process+ (fn [id client]+ id))++(defmethod apply-process ::keep-alive [_ client]+ {::client/client client+ ::processes [{::process-id ::keep-alive+ ::process-timeout 20000}]+ ::messages+ [{::msg/id ::cl/keep-alive+ :id (long (* (rand) Long/MAX_VALUE))}]}) (defmulti apply-message "'Applies' a message to a client state. Returns the new client state, as well@@ -97,4 +110,5 @@ {::msg/id ::cl/game-event :event :wait-for-chunks}]- ::keep-alive? true})+ ::processes [{::process-id ::keep-alive+ ::process-timeout 20000}]})src/net/bowmap/minecraft_server.clj view file
@@ -3,7 +3,6 @@ [clojure.core.async :refer [<!! >!! alt!! chan io-thread put! timeout]] [net.bowmap.message-application :as a] [net.bowmap.network.client :as client]- [net.bowmap.network.message :as msg] [net.bowmap.network.message.client :as cl] [net.bowmap.network.message.server :as srv] [net.bowmap.network.server :as server]@@ -11,43 +10,50 @@ ; The logical server, holds a set of clients connected -(defn keep-alive! [messages-out]- (io-thread- (loop []- (<!! (timeout 20000))- (put! messages-out {::msg/id ::cl/keep-alive- :id (long (* (rand) Long/MAX_VALUE))})- (recur))))+(defn run-effects! [messages-out process-chan result]+ ; Schedule processes+ (let [{:keys [::client/client ::a/processes ::a/messages]} result]+ ;; Processes to start+ (doseq [{::a/keys [process-id process-timeout]} processes]+ (io-thread+ (<!! (timeout process-timeout))+ (>!! process-chan process-id)))+ (doseq [msg messages]+ (put! messages-out msg))+ client)) (defn read-and-handle-packet! "Reads/deserializes one packet into a message, and handles it. Because packet reading is dependent on the state of the client, and handling a packet can update the state of the client, Reading and handling must be synchronized!"- [pk client messages-out]+ [pk client messages-out process-chan] (when-some [msg (srv/packet->message pk (::state/connection-state client))]- (let [{:keys [::client/client ::a/keep-alive? ::a/messages]} (a/apply-message msg client)]- (when keep-alive?- (keep-alive! messages-out))- (doseq [msg messages]- (put! messages-out msg))- client)))+ (run-effects! messages-out process-chan (a/apply-message msg client)))) -(defn handle-packets-and-messages! [client packets-in messages-out packets-out]+(defn handle-process! [process-id client messages-out process-chan]+ (run-effects! messages-out process-chan (a/apply-process process-id client)))++(defn handle-packets-and-messages! [client packets-in messages-out packets-out process-chan] (alt!!+ ; Timeouts?+ ; TODO should take the old process map so you can reuse timeouts if you want to!+ process-chan ([process-id]+ (handle-process! process-id client messages-out process-chan)) messages-out ([msg] (when msg (assert (>!! packets-out (cl/message->packet msg (::state/connection-state client)))) client)) packets-in ([pk] (when pk- (read-and-handle-packet! pk client messages-out)))))+ (read-and-handle-packet! pk client messages-out process-chan))))) (defn connect! [client packets-in packets-out]- (let [messages-out (chan 1024)]+ (let [messages-out (chan 1024)+ process-chan (chan 64)] ; TODO error handling and disconnect (io-thread (loop [client client]- (when-some [client (handle-packets-and-messages! client packets-in messages-out packets-out)]+ (when-some [client (handle-packets-and-messages! client packets-in messages-out packets-out process-chan)] ; Otherwise, stop? (recur client)))) nil))