Clojure:ZeroMQ的入门DEMO

假设你已经知道什么是ZeroMQ(不知道的话可以看这个:http://zh.wikipedia.org/wiki/%C3%98MQ),以下就给出在Clojure中如何使用ZeroMQ(感谢此文作者:http://patternhatch.com/2013/06/12/messaging-using-clojure-and-zeromq/)。
1.    创建一个Clojure项目,这里我们用leiin。lein new app zmq-test
2.    在project.clj文件中添加
[com.rmoquin.bundle/jeromq "0.2.0"]
cheshire "5.3.1"]]
其中jeromq就是我们需要使用的ZeroMQ类库(纯Java实现),cheshire用于双向处理json。
3.    打开core.clj文件,输入如下代码:

 1 (ns zmq-test.core
 2   (:import [org.jeromq ZMQ])
 3   (:require (cheshire [core :as c])))
 4 
 5 (def ctx (ZMQ/context 1))
 6 
 7 ;; REQ/REP [Request-Reply] Pattern
 8 ;; In REPL, input
 9 ;;   (future-call echo-server)
10 ;;   (echo "hi")
11 ;; to run the demo function
12 (defn echo-server
13   []
14   (let [s (.socket ctx ZMQ/REP)]
15     (.bind s "tcp:// 127.0.0.1:5555")
16     (loop [msg (.recv s)]
17       (.send s msg)
18       (recur (.recv s)))))
19 
20 (defn echo
21   [msg]
22   (let [s (.socket ctx ZMQ/REQ)]
23     (.connect s "tcp:// 127.0.0.1:5555")
24     (.send s msg)
25     (println "Server replied:" (String. (.recv s)))
26     (.close s)))
27 
28 ;; PUB/SUB [Publish-Subscribe] Pattern
29 ;; In REPL, input
30 ;;   (future-call market-data-publisher)
31 ;;   (get-market-data 100)
32 ;; to run the demo function
33 (defn market-data-publisher
34   []
35   (let [s (.socket ctx ZMQ/PUB)
36         market-data-event (fn []
37                             {:symbol (rand-nth ["CAT" "UTX"])
38                              :size (rand-int 1000)
39                              :price (format "%.2f" (rand 50.0))})]
40     (.bind s "tcp:// 127.0.0.1:6666")
41     (while :true
42       (.send s (c/generate-string (market-data-event))))))
43 
44 (defn get-market-data
45   [num-events]
46   (let [s (.socket ctx ZMQ/SUB)]
47     (.subscribe s "")
48     (.connect s "tcp://127.0.0.1:6666")
49     (dotimes [_ num-events]
50       (println (c/parse-string (String. (.recv s)))))
51     (.close s)))
52 
53 ;; PUSH/PULL [Pipeline] Pattern
54 ;; In REPL, input
55 ;;   (future-call collector)
56 ;;   (future-call worker)
57 ;;   (future-call worker)
58 ;;   (future-call worker)
59 ;;   (dispatcher 100)
60 ;; to run the demo function
61 (defn dispatcher
62   [jobs]
63   (let [s (.socket ctx ZMQ/PUSH)]
64     (.bind s "tcp://127.0.0.1:7777")
65     (Thread/sleep 1000)
66     (dotimes [n jobs]
67       (.send s (str n)))
68     (.close s)))
69 
70 (defn worker
71   []
72   (let [rcv (.socket ctx ZMQ/PULL)
73         snd (.socket ctx ZMQ/PUSH)
74         id (str (gensym "w"))]
75     (.connect rcv "tcp://127.0.0.1:7777")
76     (.connect snd "tcp://127.0.0.1:8888")
77     (while :true
78       (let [job-id (String. (.recv rcv))
79             proc-time (rand-int 100)]
80         (Thread/sleep proc-time)
81         (.send snd (c/generate-string {:worker-id id
82                                        :job-id job-id
83                                        :processing-time proc-time}))))))
84 
85 (defn collector
86   []
87   (let [s (.socket ctx ZMQ/PULL)]
88     (.bind s "tcp://127.0.0.1:8888")
89     (while :true
90       (->> (.recv s)
91            (String.)
92            (c/parse-string)
93            (println "Job completed:")))))

代码中包括了ZeroMQ的三种模式,可以直接在REPL中进行测试。但是这只是很简单的Hello World程序,如果要将ZeroMQ用于实际生产环境中的话,还有很多环节需要考虑和完善。

posted @ 2014-09-25 10:30  GreatK  阅读(2123)  评论(0编辑  收藏  举报