基于元数据管理Aleph(clojure)中的连接

时间:2013-05-15 13:24:54

标签: clojure websocket

我写过一个非常简单的广播/回送服务器,它使用带有clojure和aleph的网络套接字。

我花了很多时间浏览aleph和lamina来源,以获得一个体面的,基本的了解这里发生的事情。

我想做什么

  1. 建立来自客户的连接
  2. 偶尔向服务器发送说明
  3. 执行指令并根据有关连接的某些元数据将响应发送给其他人
  4. 因此,这可以处理数据(这很棒)并格式化响应(这很棒)。如何才能将响应仅发送给相关方?

    到目前为止我有什么

    (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中以这种方式管理连接...任何帮助?

2 个答案:

答案 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)))