一、ZeroMQ並非一個對socket的封裝,不能用它去實現已有的網絡協議。python
二、有本身的模式,不一樣於更底層的點對點通信模式。服務器
三、有比tcp協議更高一級的協議(固然ZeroMQ不必定基於TCP協議,它也能夠用於進程間和進程內通信)。網絡
四、改變了通信都基於一對一的鏈接這個假設。socket
一、請求應答模型tcp
由請求端發起請求,並等待迴應端迴應請求。從請求端來看,必定是一對對收發配對的;反之,在迴應端必定是發收對。請求端和迴應端均可以是1:N的模型。一般把1認爲是server,N認爲是Client。0MQ能夠很好的支持路由功能(實現路由功能的組件叫作Device),把1:N擴展爲N:M(只須要加入若干路由節點)。從這個模型看,更底層的端點地址是對上層隱藏的。每一個請求都隱含迴應地址,而應用則不關心它。ide
二、發佈訂閱模型spa
這個模型裏,發佈端是單向只發送數據的,且不關心是否把所有的信息都發送給訂閱者。若是發佈端開始發佈信息的時候,訂閱端還沒有鏈接上,這些信息直接丟棄。不過一旦訂閱鏈接上來,中間會保證沒有信息丟失。一樣,訂閱端則只負責接收,而不能反饋。若是發佈端和訂閱端須要交互(好比要確認訂閱者是否已經鏈接上),則使用額外的socket採用請求迴應模型知足這個需求。code
三、管道模型server
這個模型裏,管道是單向的,從PUSH端單向的向PULL端單向的推送數據流。blog
應答模式,就是一問一答,規則有這麼幾條:
一、 必須先提問,後回答
二、 對於一個提問,只能回答一次
三、 在沒有收到回答前不能再次提問
上代碼,服務端:
#coding=utf-8 import zmq import time context = zmq.Context() socket = context.socket(zmq.REP) socket.bind('tcp://127.0.0.1:8000') while True: message = socket.recv() print 'received request: ' ,message time.sleep(1) socket.send('World')
客戶端:
#coding=utf-8 ''''' 你沒法連續向服務器發送數據,必須發送一次,接收一次 REQ和REP模式中,客戶端必須先發起請求 ''' import zmq context = zmq.Context() print 'connect to hello world server' socket = context.socket(zmq.REQ) socket.connect('tcp://127.0.0.1:8000') for request in range(1,10): print 'send ',request,'...' socket.send('hello') message = socket.recv() print 'received reply ',request,'[',message,']'
說明:
客戶端老是必須先提問,客戶端提問後,必須等待回答,在收到回答前若是又發出提問,那麼會報錯。
zmq.REP是應答方,zmq.REQ是提問方,顯然,咱們能夠有多個提問方,但只能有一個提問方。
問題1:應答方和提問方誰先啓動呢?(服務端和客戶端誰先啓動呢?)
答:誰先啓動均可以,和pub/sub模式同樣
問題2:若是服務端斷掉或者客戶端斷掉會產生怎樣的影響?
答:若是是客戶端斷掉,對服務端沒有任何影響,若是客戶端隨後又從新啓動,那麼兩方繼續一問一答,可是若是是服務端斷掉了,就可能會產生一些問題,這要看服務端是在什麼狀況下斷掉的,若是服務端是在回答完問題後斷掉的,那麼沒影響,重啓服務端後,雙發繼續一問一答,但若是服務端是在收到問題後斷掉了,還沒來得及回答問題,這就有問題了,那個提問的客戶端遲遲得不到答案,就會一直等待答案,所以不會再發送新的提問,服務端重啓後,客戶端遲遲不發問題,因此也就一直等待提問。
問題3: 看代碼,服務端根本就沒去區分提問者是誰,若是有兩個提問題的人,如何保證服務端的答案准確的發給那個提問的客戶端呢?
答:關於這一點,你們沒必要擔憂,zmq的內部機制已經作了保證,提問者必然只收到屬於本身的答案,咱們沒必要去操心zmq是怎麼作到的,你只需關於業務自己便可。
如今,咱們把服務端代碼作修改
#coding=utf-8 import zmq import time context = zmq.Context() socket = context.socket(zmq.REP) socket.bind('tcp://127.0.0.1:8000') while True: message = socket.recv() print 'received request: ' ,message time.sleep(1) if message == 'hello': socket.send('World') else: socket.send('success')
#coding=utf-8 import zmq context = zmq.Context() print 'connect to hello world server' socket = context.socket(zmq.REQ) socket.connect('tcp://127.0.0.1:8000') for request in range(1,10): print 'send ',request,'...' socket.send('hello') message = socket.recv() print 'received reply ',request,'[',message,']'
#coding=utf-8 import zmq context = zmq.Context() print 'connect to hello world server' socket = context.socket(zmq.REQ) socket.connect('tcp://127.0.0.1:8000') for request in range(1,10): print 'send ',request,'...' socket.send('ok') message = socket.recv() print 'received reply ',request,'[',message,']'
實際的運行結果如圖:
不難看出,每一個客戶端都收到了只屬於本身的答案