我写过一个非常简单的广播/回送服务器,它使用带有clojure和aleph的网络套接字。
我花了很多时间浏览aleph和lamina来源,以获得一个体面的,基本的了解这里发生的事情。
因此,这可以处理数据(这很棒)并格式化响应(这很棒)。如何才能将响应仅发送给相关方?
(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}))
假设我在JSON中有这个请求:
{"room":32, "color":"red", "command":"do something..."}
我希望这可以执行“do something ...”命令,然后将结果输出发送给其最近命令包含的所有其他人{“room”:32,“color”:“red”}
我不明白如何在aleph中以这种方式管理连接...任何帮助?
答案 0 :(得分:3)
如果您希望更多粒度接收哪些消息,则需要比“广播频道”更精细的内容。 Lamina提供(named-channel ...)
函数,允许您创建自己的通道命名空间。
这看起来像是:
(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)))
在这种情况下,subscribe
方法确保客户端连接将接收来自该特定通道的所有消息,并返回将取消该订阅的函数。你需要有一些持有这些取消回调的每个客户端状态,但我会将其作为练习留给读者。
答案 1 :(得分:0)
您可以尝试以下内容:
(defn ws-handler [ch request]
(let [last-msg (atom nil)]
(siphon (map* #(do (swap! last-msg (constantly %)) [% (do-something %)]) ch) broadcast-channel)
(siphon (map* second (filter* (fn [[msg v]] (= @last-msg msg)) broadcast-channel)) ch)))