python與zmq系列(5)
阿新 • • 發佈:2018-11-04
我們已經瞭解REQ/REP,PUB/SUB,PULL/PUSH這三種模式,也曾提到過,一個上下文可以建立多個socket套接字,那麼如何管理這些套接字呢?
假設我們的一個客戶端既有pull又有sub,他們兩個都需要接收訊息,該如何協調呢,畢竟,當一個socket要收訊息的時候,函式recv是阻塞的,所以,我們第一個思路是不讓它阻塞,看示例程式碼:
-
#coding=utf-8
-
'''
-
Created on 2015-10-13
-
在這裡,同時處理多個套接字,那麼接收訊息的時候,就需要設定noblock
-
不然會在第一個接收訊息的地方堵塞
-
@author: kwsy2015
-
'''
-
import zmq
-
import time
-
-
# Prepare our context and sockets
-
context = zmq.Context()
-
-
# Connect to task ventilator
-
receiver = context.socket(zmq.PULL)
-
receiver.connect(
"tcp://localhost:5557")
-
-
# Connect to weather server
-
subscriber = context.socket(zmq.SUB)
-
subscriber.connect(
"tcp://localhost:5556")
-
subscriber.setsockopt(zmq.SUBSCRIBE,
b"10001")
-
-
# Process messages from both sockets
-
# We prioritize traffic from the task ventilator
-
while
True:
-
-
# Process any waiting tasks
-
while
True:
-
try:
-
#用了NOBLOCK,就意味著得不到訊息時不會堵塞在這裡
-
msg = receiver.recv(zmq.NOBLOCK)
-
except zmq.ZMQError:
-
break
-
# process task
-
-
# Process any waiting weather updates
-
while
True:
-
try:
-
msg = subscriber.recv(zmq.NOBLOCK)
-
except zmq.ZMQError:
-
break
-
# process weather update
-
-
# No activity, so sleep for 1 msec
-
time.sleep(
0.001)
通過設定zmq.NOBLOCK,我們可以讓recv不再阻塞,但是呢,要捕捉zmq.ZMQError這個異常,這樣一來,兩個套接字就可以不發生衝突了
但是明顯,你可以感受得到,這種做法的醜陋,看起來不是那麼的優雅,所以我們換一種做法
-
#coding=utf-8
-
'''
-
Created on 2015-10-13
-
這種方式比msreader要更好一些
-
@author: kwsy2015
-
'''
-
import zmq
-
-
# Prepare our context and sockets
-
context = zmq.Context()
-
-
# Connect to task ventilator
-
receiver = context.socket(zmq.PULL)
-
receiver.connect(
"tcp://localhost:5557")
-
-
# Connect to weather server
-
subscriber = context.socket(zmq.SUB)
-
subscriber.connect(
"tcp://localhost:5556")
-
subscriber.setsockopt(zmq.SUBSCRIBE,
b"10001")
-
-
# Initialize poll set
-
poller = zmq.Poller()
-
poller.register(receiver, zmq.POLLIN)
-
poller.register(subscriber, zmq.POLLIN)
-
-
# Process messages from both sockets
-
while
True:
-
try:
-
socks = dict(poller.poll())
-
except KeyboardInterrupt:
-
break
-
-
if receiver
in socks:
-
message = receiver.recv()
-
# process task
-
-
if subscriber
in socks:
-
message = subscriber.recv()
-
# process weather update
這種做法就很想socket的select模式,大家誰也別爭,誰也別搶,只要有訊息達到,我就通知你們,然後你們各自檢查是不是自己的訊息。我們在客戶端建立多個socket套接字可能是合理的,但是服務端就最好別這麼做了,REQ,PUSH,PUB,道理其實也很簡單,服務就是服務,多個員工可以擠在一個辦公司裡辦公,哪有多個老闆擠在一起辦公的。