[英]How to filter in PUB/SUB ( ZeroMQ ) with protobuf binaries?
[英]PUB/SUB pattern in ZeroMQ not working
我正在尝试使用ZeroMQ实现非常基本的PUB/SUB
模式。 我希望有一台服务器(始终处于活动状态)向所有客户端广播消息(发布者),并且不关心已连接的客户端。 如果客户端以订户身份连接到此服务器,则它应收到该消息。
但是,我无法使用PUB/SUB
发送消息。
在Python中将是:
# publisher (server.py)
import zmq
ctx = zmq.Context()
publisher = ctx.socket(zmq.PUB)
publisher.bind('tcp://127.0.0.1:9091')
while True:
publisher.send_string("test")
和
# subscriber (client.py)
import zmq
ctx = zmq.Context()
subscriber = ctx.socket(zmq.SUB)
subscriber.connect('tcp://127.0.0.1:9091')
while True:
msg = subscriber.recv_string()
print msg
或在golang中:
package main
import (
"github.com/pebbe/zmq4"
"log"
"time"
)
func Listen(subscriber *zmq4.Socket) {
for {
s, err := subscriber.Recv(0)
if err != nil {
log.Println(err)
continue
}
log.Println("rec", s)
}
}
func main() {
publisher, _ := zmq4.NewSocket(zmq4.PUB)
defer publisher.Close()
publisher.Bind("tcp://*:9090")
subscriber, _ := zmq4.NewSocket(zmq4.SUB)
defer subscriber.Close()
subscriber.Connect("tcp://127.0.0.1:9090")
go Listen(subscriber)
for _ = range time.Tick(time.Second) {
publisher.Send("test", 0)
log.Println("send", "test")
}
}
连接时我是否误解了这种模式,还是需要从客户端向服务器发送特定信号? 我对golang版本感兴趣,仅使用python版本进行测试。
ZeroMQ原型被定义为代表某种行为。 至于说, PUSH
-archetype存取点“到”所有迄今建立沟通渠道推动每一个消息, PULL
-er存取点拉什么,已经到达了线(县)“它的手”, PUB
-lisher存取点公布, SUB
- scriber AccessPoint进行订阅,以便仅接收与其主题过滤器匹配的消息,但不匹配其他任何消息。
显然,这种原型“规范”有助于构建ZeroMQ智能消息传递/信令基础结构,以使我们易于在分布式系统体系结构中使用。
# subscriber (client.py)
import zmq
ctx = zmq.Context()
subscriber = ctx.socket( zmq.SUB )
subscriber.connect( 'tcp://127.0.0.1:9091' )
subscriber.setsockopt( zmq.LINGER, 0 ) # ALWAYS:
subscriber.setsockopt( zmq.SUBSCRIBE, "" ) # OTHERWISE NOTHING DELIVERED
while True:
msg = subscriber.recv_string() # MAY USE .poll() + zmq.NOBLOCK
print msg
subscriber, _ := zmq4.NewSocket( zmq4.SUB )
subscriber.Connect( "tcp://127.0.0.1:9090" )
subscriber.SetSubscribe( filter ) // SET: <topic-filter>
subscriber.SetLinger( 0 ) // SAFETY FIRST: PREVENT DEADLOCK
defer subscriber.Close() // NOW MAY SAFELY SET:
...
msg, _ := subscriber.Recv( 0 )
根据定义,任何右实例化的SUB
AccessPoint对象实际上都有零机会知道,什么消息是那些正确消息的选择是什么,因此应该“传递”这些消息而不是什么消息。
如果没有这一块初步知识,ZeroMQ设计师有一个主要的选择是要么原型政策一致,让PUB
侧的接入节点,来分配所有的.send()
-acquired消息只对那些SUB
侧的接入节点(S),有明确要求接收任何这样的,对通过zmq.SUBSCRIBE
-mechanics 或提供了从发送PUB
也给所有迄今未决定的SUB
-s。
前者是ZeroMQ作者的一致而专业的设计步骤。
后者实际上意味着违反ZeroMQ自己的RFC规范。
后一种选择就像是有人刚搬到新公寓,几乎不会期望从第二天早上开始,所有报纸和杂志都出现在新邮箱中,是吗? 但是,如果有人订阅《波士顿环球报》,则第二天早晨,新发行版将在门口,因为它将继续留在那儿,直到有人取消订阅,报纸破产或缺少纸卷而阻止印刷厂交付为止在适当的时间和方式,或者Big Dig隧道中的交通拥堵可能会在某一天造成全部或仅本地交付的麻烦。
所有这一切都是自然的,并且与原型策略兼容。
Intermezzo: Golang已经绑定到许多不同的API版本
技术纯粹主义者在这里会反对,早期的API版本(直到一些v3.2 +版本)实际上确实将所有消息有效负载从PUB
传输到所有SUB
-s,因为它简化了PUB
端的工作量范围,但增加了传输类( es)数据流和SUB
端资源/延迟的主题过滤器处理。 然而,就API抽象的观点而言,所有这些都对用户代码不可见。 因此,除了需要适当扩展资源外,这对用户是透明的。 最新的API版本恢复了主题过滤器处理器的角色,现在让它在PUB
端发生。 尽管如此,在两种情况下,ZeroMQ RFC规范策略都是以这种方式实现的, SUB
端永远不会(通过.recv()
传递与有效的显式SUB
端不匹配的单个消息。认购(S)
在所有情况下, SUB
zmq.SUBSCRIBE
尚未显式设置任何zmq.SUBSCRIBE
指示的主题过滤器, 它不能也不会提供任何内容 (这是自然的,并且与为SUB
定义的ZeroMQ RFC Archetype-policy完全一致-键入AccessPoint)。
至少始终要阅读ZeroMQ API文档,该文档中的所有详细信息都是经过专业指定的-至少,这样的用户至少可以一窥智能消息传递/信令框架的气息。
这将不会帮助任何人从绿色领域开始,并完全建立自己复杂的思维概念,并且对所有事物在内部如何工作有深入的了解,这显然不是任何API文档的野心,对吗? 但是,一旦掌握了ZeroMQ内部架构(如在下一段中提到的源中所述),这将帮助任何人刷新或提醒所有可配置的细节。
另外,对于确实对分布式系统感兴趣或仅每秒零平方米的人来说,花时间和精力来始终阅读Pieter HINTJENS的著作“ Code Connected,Volume 1”(可免费以pdf格式)以及任何其他书籍,这是值得的。之所以选择他的书,是因为他后来在软件工程方面的丰富经验,因为他对现代计算的许多见识可能并且将会激发很多。
编辑:
package main
import (
"github.com/pebbe/zmq4"
"log"
"time"
)
func Listen(subscriber *zmq4.Socket) {
for {
s, err := subscriber.Recv(0)
if err != nil {
log.Println(err)
continue
}
log.Println("rec", s)
}
}
func main() {
publisher, _ := zmq4.NewSocket(zmq4.PUB)
publisher.SetLinger(0)
defer publisher.Close()
publisher.Bind("tcp://127.0.0.1:9092")
subscriber, _ := zmq4.NewSocket(zmq4.SUB)
subscriber.SetLinger(0)
defer subscriber.Close()
subscriber.Connect("tcp://127.0.0.1:9092")
subscriber.SetSubscribe("")
go Listen(subscriber)
for _ = range time.Tick(time.Second) {
publisher.Send("test", 0)
log.Println("send", "test")
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.