浏览 3004 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-03-25
最后修改:2011-03-25
而在实际的应用中,绝大多数会出现这样的结构要求: zeroMQ中自然也提供了这样的需求案例: 1.发布/订阅 代理模式: import zmq context = zmq.Context() frontend = context.socket(zmq.SUB) frontend.connect("tcp://192.168.55.210:5556") backend = context.socket(zmq.PUB) backend.bind("tcp://10.1.1.0:8100") frontend.setsockopt(zmq.SUBSCRIBE, '') while True: while True: message = frontend.recv() more = frontend.getsockopt(zmq.RCVMORE) if more: backend.send(message, zmq.SNDMORE) else: backend.send(message) break # Last message part 注意代码,这个代理是支持大数据多包发送的。这个proxy实现了下图: 2.请求/答复 代理模式: 因为zeroMQ天然支持"多对多",所以看似不需要代理啊,如下图: 不过,这样会有一个问题,客户端需要知道所有的服务地址,并且在服务地址出现变迁时,需要通知客户端,这样迁移扩展的复杂度将无法预估。故,需要实现下图: 客户端: import zmq context = zmq.Context() socket = context.socket(zmq.REQ) socket.connect("tcp://localhost:5559") for request in range(1,10): socket.send("Hello") message = socket.recv() print "Received reply ", request, "[", message, "]" 服务器端: import zmq context = zmq.Context() socket = context.socket(zmq.REP) socket.connect("tcp://localhost:5560") while True: message = socket.recv() print "Received request: ", message socket.send("World") 代理端: import zmq context = zmq.Context() frontend = context.socket(zmq.XREP) backend = context.socket(zmq.XREQ) frontend.bind("tcp://*:5559") backend.bind("tcp://*:5560") poller = zmq.Poller() poller.register(frontend, zmq.POLLIN) poller.register(backend, zmq.POLLIN) while True: socks = dict(poller.poll()) if socks.get(frontend) == zmq.POLLIN: message = frontend.recv() more = frontend.getsockopt(zmq.RCVMORE) if more: backend.send(message, zmq.SNDMORE) else: backend.send(message) if socks.get(backend) == zmq.POLLIN: message = backend.recv() more = backend.getsockopt(zmq.RCVMORE) if more: frontend.send(message, zmq.SNDMORE) else: frontend.send(message) 上面的代码组成了下面的网络结构: 客户端与服务器端互相透明,世界一下清净了... 这节上了好多图和代码,绝对都是干货。不过,既然0mq已经想到了,为毛还要咱自己写代理捏?So,虽然上面的都是干货,或许,马上,就可以统统忘掉了。下面,展示下0mq自带的代理方案: import zmq def main(): context = zmq.Context(1) frontend = context.socket(zmq.XREP) frontend.bind("tcp://*:5559") backend = context.socket(zmq.XREQ) backend.bind("tcp://*:5560") zmq.device(zmq.QUEUE, frontend, backend) frontend.close() backend.close() context.term() if __name__ == "__main__": main() 这是应答模式的代理,官方提供了三种标准代理: 应答模式:queue XREP/XREQ 订阅模式:forwarder SUB/PUB 分包模式:streamer PULL/PUSH 特别提醒: 官方可不推荐代理混搭,不然责任自负。按照官方的说法,既然要混搭,还是自个儿写代理比较靠谱~ (未完待续) 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |