ZMQ 高级请求-应答封包解包

我理解的ZMQ

ZMQ不是消息队列, 是一套构建消息队列的组件集合, 它告诉你每个组件有什么特性, 每个组件可以干什么, 至于怎么构建消息队列, 全凭自己决定. 我们可以搭建出同步的, 异步的, 可靠的, 不可靠的, 分布式的, 非分布式的等等. 正是这种灵活的方式, ZMQ才能满足各式各样的需求(借别人一句话:ZMQ就像是一盒积木,只要你有足够的想象力,就可以用它组装出任何造型的网络架构).

扩展请求应答模式

REQ-ROUTER-DEALER-REP, 在req-rep中间加入代理层.

为什么要扩展请求问答模型?

从图中我们可以看到, 一问一答还是原来的一问一答, 但是是谁在问, 又是谁在答, 这个边界已经被ROUTER-DEALER取代了. 这样REQ的请求怎么到达REP, REP的回答又怎么回到正确的REQ, 这就关系到我要说的主题请求-应答封包解包.

REQ 封包

REQ封包是两帧消息, 第一帧为空的分割符帧, 第二帧为正文, 网上很多第二帧写了个地址, 有误导性.

REQ 解包

REQ 收到的只会是两帧消息, 第一帧为空的分隔符帧, 第二帧为正文, 解包的时候会丢掉分隔符帧, 然后把正文传给程序.

REP 解包

REP是一问一答, 所以一定是先收到然后发送. REP 收到的是多帧消息(至少两帧), 最后一帧消息是正文, 倒数第二帧为分隔符帧, 然后从第一帧到倒数第二帧之间全为地址帧. REP 执行解包的时候, 会解去地址帧直到包括分割符帧, 然后保存整个封包(这个非常重要).

REP 封包

REP 封包为多帧消息, 前面n帧为解包获得的地址帧(如果没有就没有), 然后是空的分割符帧, 最后是正文.

所以REQ-REP一定是一问一答模式, 否则包顺序就会乱.

ROUTER

ROUTER 套接字跟踪它具有的每一个连接, 并告诉这些调用者. 它告诉调用者的方法是, 在所接受的每个消息前面添加一个地址帧.

ROUTER 解包(接收消息)

ROUTER接收到的是多帧消息, 具体分为两部分, 第二部分为收到的消息, 第一部分则是自己主动附加的地址帧.

ROUTER 封包(发送消息)

ROUTER发送的是多帧消息, 并且会主动删除第一个地址帧(解包的逆向), 也就是说发送的消息至少是两帧, 第一帧一定是地址帧, ROUTER通过第一帧, 找到需要发送的连接, 然后删掉这一帧, 最后把剩下的所有帧发送给这个连接.

s_sendmore(broker, identity);     // 发送的这帧消息, 会被ROUTER删掉, 连接的另一方只会收到下面两帧消息
s_sendmore(broker, "");
s_send(broker, "The quick brown fox jumps over the lazy dog");

DEALER

DEALER 对封包解包一无所知, 并像处理任何多部分消息一样处理它. 它将发送的消息分发给所有连接, 并对从所有连接收到的消息公平的进行排队.

总结

ROUTER 和 DEALER 是异步的, 我们可以用他们创建相对req-rep更加高效的网络框架. 通过理解这种封包解包的机制, 我们可以组合出更多的消息模型, 同时也能理解为什么有些消息模型是错误的(比如:REQ-DEALER).

欢迎大家订阅雀观代码, 我将给你讲述, 中小企业程序员, 淘金路上的故事.



发表评论

电子邮件地址不会被公开。 必填项已用*标注