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,如果输出如下就表示运行正常。