I've written a very simple broadcast/echo server that uses web sockets with clojure and aleph.
I spent a lot of time looking through the aleph and lamina sources to get a decent, basic understand what's happening here.
So this can process the data (which is great) and format the response (which is great). How can I get it to send the response only to relevant parties?
(defn do-something
[arg]
(str "pickles" "are" "nice" arg))
(defn ws-handler [ch request]
(siphon (map* #(do-something %) ch) broadcast-channel)
(siphon broadcast-channel ch))
(defn -main
"Start the http server"
[& args]
(start-http-server ws-handler {:port 8080 :websocket true}))
Let's say I had this request in JSON:
{"room":32, "color":"red", "command":"do something..."}
I would want this to execute the "do something..." command, then the resultant output would be sent to everyone else whose most recent command had included {"room":32, "color":"red"}.
I don't understand how to manage connections this way in aleph... any help?
If you want more granularity in who receives what message, you need something more granular than a "broadcast-channel". Lamina provides a (named-channel ...) function which allows you to create your own namespace of channels.
This would look something like:
(defn broadcast [channel-name message]
(enqueue (named-channel channel-name nil) message))
(defn subscribe [channel-name client-channel]
(let [bridge-channel (channel)]
(siphon
(named-channel channel-name nil)
bridge-channel
client-channel)
#(close bridge-channel)))
The subscribe method, in this case, ensures that the client connection will receive all messages from that particular channel, and returns a function that will cancel that subscription. You'll need to have some per-client state that holds onto those cancellation callbacks, but I'll leave that as an exercise for the reader.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With