Clojure:通过ZeroMQ推送消息

通过ZeroMQ的pub/sub模式,我们可以实现发送推送消息的功能。以下为示例代码(入门可参考此文:http://www.cnblogs.com/ilovewindy/p/3984269.html):

 1 (def ctx (ZMQ/context 1))
 2 
 3 (def msg-list (atom ()))                                    ; 消息列表
 4 (def stop-signal (atom false))                              ; 停止发送服务标识
 5 
 6 (defn msg-publisher
 7   []
 8   (let [s (.socket ctx ZMQ/PUB)]
 9     (.bind s “tcp://x.x.x.x:xxxx”)
10     (while (false? @stop-signal)                            ; 遇到停止信号则退出发送循环
11       (loop [msgs @msg-list]                                ; 对消息列表进行循环发送处理
12         (if (empty? msgs)
13           (do
14             (reset! msg-list ())                            ; 全部发送后清空消息列表
15             (.send s (c/generate-string "0"))               ; 发送结束标识
16             (Thread/sleep 1000)                             ; 延时1秒后再重新读取,以免发送空数据太频繁
17             )
18           (do
19             (.send s (c/generate-string (first msgs)))      ; 发送消息
20             (recur (rest msgs)))                            ; 发送下一条消息
21           )))
22 (.close s)))

通过(future-call msg-publisher)将msg-publisher常驻线程后,msg-publisher会自动读取msg-list列表,将新增加的内容推送给客户端。下面附上测试代码:

 1 (deftest test-msg-publisher
 2   (do
 3     (let [f (future-call msg-publisher)
 4           s (.socket ctx ZMQ/SUB)]
 5       (reset! stop-signal false)
 6       f
 7       (.subscribe s ZMQ/SUBSCRIPTION_ALL)
 8       (.connect s “tcp://x.x.x.x:xxxx”)
 9       (reset! msg-list (range 10000))                       ; 产生消息10000条,但是只接收1000条,这是因为连接延时的问题,
10       (loop [exec-times 1000                                ; 导致不可能将全部消息收全
11              msg-count 0]
12         (if (= 0 exec-times)
13           (is (= 1000 msg-count))
14           (do
15             (let [msg (c/parse-string (.recvStr s))]
16               ;(println msg)
17               (if (not (= "0" msg))                         ; 如果为0则表示不是我们希望要的数据
18                 (recur (dec exec-times) (inc msg-count))
19                 (recur (dec exec-times) msg-count)))))
20         )
21       (.close s)
22       (reset! stop-signal true)
23       (future-cancel f)
24       (is (future-cancelled? f)))))


运行lein test,如果输出如下就表示运行正常。

posted @ 2014-09-29 09:31  GreatK  阅读(1500)  评论(1编辑  收藏  举报