zeroMQ初体验-2.发布订阅模式(pub/sub)

 

PythonSocket

pub/sub模式:

zeroMQ初体验-2.发布订阅模式(pub/sub)_第1张图片

发布端(pub)

Python代码  收藏代码

  1. import itertools  
  2. import sys    
  3. import time   
  4.               
  5. import zmq    
  6.               
  7. def main():   
  8.     if len (sys.argv) != 2:  
  9.         print 'usage: publisher '  
  10.         sys.exit (1)  
  11.       
  12.     bind_to = sys.argv[1]  
  13.       
  14.     all_topics = ['sports.general','sports.football','sports.basketball',  
  15.                   'stocks.general','stocks.GOOG','stocks.AAPL',  
  16.                   'weather']  
  17.       
  18.     ctx = zmq.Context()  
  19.     s = ctx.socket(zmq.PUB)  
  20.     s.bind(bind_to)  
  21.   
  22.     print "Starting broadcast on topics:"  
  23.     print "   %s" % all_topics  
  24.     print "Hit Ctrl-C to stop broadcasting."  
  25.     print "Waiting so subscriber sockets can connect..."  
  26.     print  
  27.     time.sleep(1.0)  
  28.       
  29.     msg_counter = itertools.count()  
  30.     try:  
  31.         for topic in itertools.cycle(all_topics):  
  32.             msg_body = str(msg_counter.next())  
  33.             print '   Topic: %s, msg:%s' % (topic, msg_body)  
  34.             #s.send_multipart([topic, msg_body])  
  35.             s.send_pyobj([topic, msg_body])  
  36.             # short wait so we don't hog the cpu  
  37.             time.sleep(0.1)  
  38.     except KeyboardInterrupt:  
  39.         pass  
  40.   
  41.     print "Waiting for message queues to flush..."  
  42.     time.sleep(0.5)  
  43.     s.close()  
  44.     print "Done."  
  45.   
  46. if __name__ == "__main__":  
  47.     main()  

 


订阅端(sub):

 

 

Python代码  收藏代码

  1. import sys  
  2. import time  
  3. import zmq  
  4.   
  5. def main():  
  6.     if len (sys.argv) < 2:  
  7.         print 'usage: subscriber  [topic topic ...]'  
  8.         sys.exit (1)  
  9.   
  10.     connect_to = sys.argv[1]  
  11.     topics = sys.argv[2:]  
  12.   
  13.     ctx = zmq.Context()  
  14.     s = ctx.socket(zmq.SUB)  
  15.     s.connect(connect_to)  
  16.   
  17.     # manage subscriptions  
  18.     if not topics:  
  19.         print "Receiving messages on ALL topics..."  
  20.         s.setsockopt(zmq.SUBSCRIBE,'')  
  21.     else:  
  22.         print "Receiving messages on topics: %s ..." % topics  
  23.         for t in topics:  
  24.             s.setsockopt(zmq.SUBSCRIBE,t)  
  25.     print  
  26.     try:  
  27.         while True:  
  28.             #topic, msg = s.recv_multipart()  
  29.             topic, msg = s.recv_pyobj()  
  30.             print '   Topic: %s, msg:%s' % (topic, msg)  
  31.     except KeyboardInterrupt:  
  32.         pass  
  33.     print "Done."  
  34.   
  35. if __name__ == "__main__":  
  36.     main()  



注意:
这里的发布与订阅角色是绝对的,即发布者无法使用recv,订阅者不能使用send,并且订阅者需要设置订阅条件"setsockopt"。
按照官网的说法,在这种模式下很可能发布者刚启动时发布的数据出现丢失,原因是用zmq发送速度太快,在订阅者尚未与发布者建立联系时,已经开始了数据发布(内部局域网没这么夸张的)。官网给了两个解决方案;1,发布者sleep一会再发送数据(这个被标注成愚蠢的);2,(还没有看到那,在后续中发现的话会更新这里)。
官网还提供了一种可能出现的问题:当订阅者消费慢于发布,此时就会出现数据的堆积,而且还是在发布端的堆积(有朋友指出是堆积在消费端,或许是新版本改进,需要读者的尝试和反馈,thx!),显然,这是不可以被接受的。至于解决方案,或许后面的"分而治之"就是吧。

你可能感兴趣的:(ZeroMQ)