參考網址:http://zhou-xingbo.iteye.com/blog/951859
常用的通訊模式有三類(兩個解釋都挺好,先保存下來):
1. 請求應答模式(Request-Reply)
消息雙向的,有來有往,req端請求的消息,rep端必須答復給req端
2. 訂閱發布模式 (sub 和 pub)
消息單向的,有去無回的。可按照發布端可發布制定主題的消息,訂閱端可訂閱喜歡的主題,訂閱端只會收到自己已經訂閱的主題。發布端發布一條消息,可被多個訂閱端同事收到。
3. push pull模式
消息單向的,也是有去無回的。push的任何一個消息,始終只會有一個pull端收到消息.
后續的代理模式和路由模式等都是在三種基本模式上面的擴展或變異。
1.請求回應模型。由請求端發起請求,並等待回應端回應請求。從請求端來看,一定是一對對收發配對的;
反之,在回應端一定是發收對。請求端和回應端都可以是1:N的模型。通常把1認為是server,N認為是Client。
0MQ可以很好的支持路由功能(實現路由功能的組件叫做Device),把1:N擴展為N:M(只需要加入若干路由節點)。
從這個模型看,更底層的端點地址是對上層隱藏的。每個請求都隱含回應地址,而應用則不關心它。
2.發布訂閱模型。這個模型里,發布端是單向只發送數據的,且不關心是否把全部的信息都發送給訂閱者。
如果發布端開始發布信息的時候,訂閱端尚未連接上,這些信息直接丟棄。
不過一旦訂閱端連接上來,中間會保證沒有信息丟失。
同樣,訂閱端則只負責接收,而不能反饋。
如果發布端和訂閱端需要交互(比如要確認訂閱者是否已經連接上),則使用額外的socket采用請求回應模型滿足這個需求。
3.管道模型。這個模型里,管道是單向的,從PUSH端單向的向PULL端單向的推送數據流。
我使用的是請求回應模型,server為REP模式,等待消息,client為REQ模式,向server請求消息。
一個最簡單的例子:
server.py
import zmq context = zmq.Context() socket = context.socket(zmq.REP) socket.bind("tcp://*:5555") message = socket.recv() print "message from client:", message # Send reply back to client socket.send("World")
client.py
import zmq context = zmq.Context() print "Connecting to server..." socket = context.socket(zmq.REQ) socket.connect ("tcp://localhost:5555") socket.send ("Hello") message = socket.recv() print "Received reply: ", message
運行結果:
$ python server.py
message from client: Hello
$ python client.py
Connecting to server...
Received reply: World
一個解決了我很多疑問的網址:
http://www.searchtb.com/2012/08/zeromq-primer.html
其中說明了:
a) 服務端和客戶端無論誰先啟動,效果是相同的,這點不同於Socket。
b) 在服務端收到信息以前,程序是阻塞的,會一直等待客戶端連接上來。
c) 服務端收到信息以后,會send一個“World”給客戶端。值得注意的是一定是client連接上來以后,send消息給Server,然后 Server再rev然后響應client,這種一問一答式的。如果Server先send,client先rev是會報錯的。
d) ZMQ通信通信單元是消息,他除了知道Bytes的大小,他並不關心的消息格式。因此,你可以使用任何你覺得好用的數據格式。Xml、Protocol Buffers、Thrift、json等等。