1. 程式人生 > >python與zmq系列(3)

python與zmq系列(3)

本篇部落格將介紹zmq應答模式,所謂應答模式,就是一問一答,規則有這麼幾條

        1、 必須先提問,後回答

        2、 對於一個提問,只能回答一次

        3、 在沒有收到回答前不能再次提問


        上程式碼,服務端:


  
  1. #coding=utf-8
  2. '''
  3. Created on 2015-10-10
  4. 回覆請求
  5. @author: kwsy2015
  6. '''
  7. import zmq
  8. import time
  9. context = zmq.Context()
  10. socket = context.socket(zmq.REP)
  11. socket.bind( 'tcp://*:5555')
  12. while True:
  13. message = socket.recv()
  14. print 'received request: ' ,message
  15. time.sleep( 1)
  16. socket.send( 'World')

        客戶端:


  
  1. #coding=utf-8
  2. '''
  3. Created on 2015-10-10
  4. 你無法連續向伺服器傳送資料,必須傳送一次,接收一次
  5. REQ和REP模式中,客戶端必須先發起請求
  6. @author: kwsy2015
  7. '''
  8. import zmq
  9. context = zmq.Context()
  10. print 'connect to hello world server'
  11. socket = context.socket(zmq.REQ)
  12. socket.connect( 'tcp://localhost:5555')
  13. for request in range( 1, 10):
  14. print 'send ',request, '...'
  15. socket.send( 'hello')
  16. message = socket.recv()
  17. print 'received reply ',request, '[',message, ']'

        為了滿足條件1,所以,客戶端必須先接收問題,客戶端總是必須先提問,客戶端提問後,必須等待回答,在收到回答前如果又發出提問,那麼會報錯。

        zmq.REP是應答方,zmq.REQ是提問方,顯然,我們可以有多個提問方,但只能有一個提問方,這就好比正在學生正在上課,只能有一個老師來回答問題,可以有多個學生提問,老師只能一個問題一個問題的來回答,所以嘍,必須是學生先提問,老師來回答,然後回答下一個學生的提問。


       自問自答環節:

       問題1: 應答方和提問方誰先啟動呢?(服務端和客戶端誰先啟動呢?)

            答: 誰先啟動都可以,和pub/sub模式一樣

       問題2: 如果服務端斷掉或者客戶端斷掉會產生怎樣的影響?

            答:  如果是客戶端斷掉,對服務端沒有任何影響,如果客戶端隨後又重新啟動,那麼兩方繼續一問一答,但是如果是服務端斷掉了,就可能會產生一些問題,這要看服務端是在什麼情況下斷掉的,如果服務端收是在回答完問題後斷掉的,那麼沒影響,重啟服務端後,雙發繼續一問一答,但如果服務端是在收到問題後斷掉了,還沒來得及回答問題,這就有問題了,那個提問的客戶端遲遲得不到答案,就會一直等待答案,因此不會再發送新的提問,服務端重啟後,客戶端遲遲不發問題,所以也就一直等待提問。

       問題3: 看程式碼,服務端根本就沒去區分提問者是誰,如果有兩個提問題的人,如何保證服務端的答案准確的發給那個提問的客戶端呢?

            答:  關於這一點,大家不必擔心,zmq的內部機制已經做了保證,提問者必然只收到屬於自己的答案,我們不必去操心zmq是怎麼做到的,你只需關於業務本身即可。

             現在,我們把服務端程式碼做修改

      


  
  1. #coding=utf-8
  2. '''
  3. Created on 2015-10-15
  4. @author: kwsy2015
  5. '''
  6. import zmq
  7. import time
  8. context = zmq.Context()
  9. socket = context.socket(zmq.REP)
  10. socket.bind( 'tcp://*:5555')
  11. while True:
  12. message = socket.recv()
  13. print 'received request: ' ,message
  14. time.sleep( 1)
  15. if message == 'hello':
  16. socket.send( 'World')
  17. else:
  18. socket.send( 'success')
           寫兩個客戶端

           客戶端1:


  
  1. #coding=utf-8
  2. '''
  3. Created on 2015-10-15
  4. @author: kwsy2015
  5. '''
  6. import zmq
  7. context = zmq.Context()
  8. print 'connect to hello world server'
  9. socket = context.socket(zmq.REQ)
  10. socket.connect( 'tcp://localhost:5555')
  11. for request in range( 1, 10):
  12. print 'send ',request, '...'
  13. socket.send( 'hello')
  14. message = socket.recv()
  15. print 'received reply ',request, '[',message, ']'
            客戶端2:


  
  1. #coding=utf-8
  2. '''
  3. Created on 2015-10-15
  4. @author: kwsy2015
  5. '''
  6. import zmq
  7. context = zmq.Context()
  8. print 'connect to hello world server'
  9. socket = context.socket(zmq.REQ)
  10. socket.connect( 'tcp://localhost:5555')
  11. for request in range( 1, 10):
  12. print 'send ',request, '...'
  13. socket.send( 'ok')
  14. message = socket.recv()
  15. print 'received reply ',request, '[',message, ']'

          實際的執行結果如圖:


             不難看出,每個客戶端都收到了只屬於自己的答案