ZeroMQ试用笔记之REQ & ROUTER

zeromq的尝鲜笔记之一。内容包含ROUTER socket的理解介绍,一个小代码片段,以及czmq中处理消息帧的api的用法。

试用说白了就是用zeromq写套小东西。期间必然会遇到问题,笔记的目的无非就是记录问题,加深理解。而实际上我在记录的过程中也不断地修正了一些起初想当然的错误的理解。虽说已极力避免,但由于都是自己一人的理解,错误在所难免,希望有兴趣看的同学帮我指出。

背景

目标是依赖Zeromq实现一个支持并发的server端,接收多个client的请求,略作处理后返回响应。

client端是windows上的java程序。server端则是CentOS下的cpp程序。

实现

若直接用REQ-REP模式的话,需要注意到:REP端必须严格遵循recv,send,recv,send….的步骤,倘若REP端在recv后需要一定时间的处理之后才能send,那么接下来的下一个REQ就得被迫等着了。所以从外部看,我们的REP的并发只有1。就跟下面这张图一样,步骤4的消息必须等到步骤3之后才能被接收。

这可能是有些场景下必须的,但不是我想要的。因为我们需要并发。说白了就是我们要在步骤2的执行期间,把步骤4甚至接下来的5、6都做了。

ROUTER 正是基于这样的目的才被引入的。我们之前也有过介绍,但那个介绍在我看来更像是个guide翻译。这里再加上自己的理解细说一下。

REP之所以要按部就班,因为它如果不按部就班,就不知道把响应发回给哪里,所以它必须要同步地,先recv再send。

我们再来看ROUTER。它之所以可以不按部就班,是因为它收到REQ的消息时,在消息头上加入来源地址,然后再交给客户端。发送时,取出消息第一帧作为目标地址,将空帧之后的帧进行发送。

举例来说,app1通过REQ发送给通过ROUTER接收的app2。若app1发送的是

1 ["hello"]

,经由ROUTER的处理,app2应用层得到的消息将是

1 [app1's address|empty|"hello"]

对于app2,不能只关心业务数据”hello”,还需要将app1′s address缓存下来,用以响应的回复。比如,若app2要回复”world”,需要手动构造一个有三个frame的消息:

1 [app1's address|empty|"world"]

再把这个消息交给ROUTER socket进行send,这时ROUTER会将第一帧address取出作为目标地址——也就是的REQ端——,再将空帧之后的数据发出。所以最终REQ端收到响应为:

1 ["world"]

这些步骤看起来复杂,看看C代码怎么写。zeromq给我们提供了包装库czmq,利用它我们可以很方便地做到上述的过程。
这是代码片段。

1 void *receiver = zsocket_new(ctx, ZMQ_ROUTER);
2 zsocket_bind(receiver, "ipc:///tmp/0");
3  
4 ....
5  
6 //recv message
7 zmsg_t *msg = zmsg_recv(receiver);
8 if (!msg){
9     //error handle..
10     return;
11 }
12 zframe_t *address = zmsg_unwrap (msg);
13 zframe_t *frame = zmsg_first (msg);
14 zmsg_destroy (&msg);
15  
16 //do something, it make time some times...
17  
18 //make response message
19 zmsg_t *message = zmsg_new();
20 zframe_t* body = zframe_new("world",sizeof("world"));
21  
22 zmsg_push (message, body);
23 zmsg_wrap (message, address);
24  
25 zmsg_send (&message, receiver);
26 zmsg_destroy(&message);

需要说明的是czmq里的几个函数,万万不可用错。虽然有注释,但要用对这些api首先得搞清楚里面提到的first,front在message里是怎么个位置,为此我画了个图:

1 //  Pop frame off front of message, caller now owns frame
2 //  If next frame is empty, pops and destroys that empty frame.
3 zframe_t *
4     zmsg_unwrap (zmsg_t *self);
1 //  Return first frame in message, or null
2 zframe_t *
3     zmsg_first (zmsg_t *self);
1 //  Push frame to front of message, before first frame
2 void
3     zmsg_push (zmsg_t *self, zframe_t *frame);
1 //  Push frame to front of message, before first frame
2 //  Pushes an empty frame in front of frame
3 void
4     zmsg_wrap (zmsg_t *self, zframe_t *frame);

所以回头看代码片段,我们在构造响应消息时先push了一个填充着"world"的帧。再zmsg_wrap了一个填充着address的帧。
zmsg_wrap做了两个事情:1)在"world"之前放上address的帧; 2)在这个帧front放个空帧。

时间: 2024-09-11 19:15:36

ZeroMQ试用笔记之REQ & ROUTER的相关文章

Cloud Foundry参赛博文——cloudfoundry 试用笔记

问题描述 我参加了CloudFoundry博客征文大赛,我的参赛作品是:cloudfoundry试用笔记内容如下:从http://rubyforge.org/frs/?group_id=167&release_id=4633下载最新的ruby环境当你安装了CloudFoundry的命令行界面(CLI)vmc之后,你可以部署Ruby,Node.js,Java等CloudFoundry支持的程序.[译者注:你得申请了开发者帐号]取决于你的网络情况,你或许在安装vmc之前需要先配置好代理程序.使用vm

zeromq学习笔记2——简单的客户端和服务端测试程序

1.前言 zeromq提供了guide,http://zguide.zeromq.org/,可以帮助新手快速上手,提供了C\C++\PHP等多种语言. 2.测试程序 使用zeromq给的hwserver和hwclient的C语言测试程序. hwserver代码如下: 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <string.h> 4 #include <assert.h> 5 #include

zeromq学习笔记1——centos下安装 zeromq-4.1.2

1.前言 MQ(message queue)是消息队列的简称,可在多个线程.内核和主机盒之间弹性伸缩.ZMQ的明确目标是"成为标准网络协议栈的一部分,之后进入Linux内核".现在还未看到它们的成功.但是,它无疑是极具前景的.并且是人们更加需要的"传统"BSD套接字之上的一 层封装.ZMQ让编写高性能网络应用程序极为简单和有趣. 2.安装过程 (1)下载最新的ZeroMQ:http://download.zeromq.org/ (2)解压:tar -xvf zero

米聊PC版试用笔记 能否媲美QQ?

小米公司宣布收购MSNLite之后的第一个大动作就是推出了米聊的PC客户端,在手机平台上取得不错成绩后,米聊将目光转向了PC桌面,并不规避与腾讯的竞争,与QQ.微信展开正面较量.今天,米聊PC版开始了第一轮内测,笔者有幸拿到了激活码,下面带领大家一睹米聊PC版的风采: 首先,拿到激活码后来到激活页面,输入米聊号与激活码进行激活,然后就可以下载"米聊PC内测客户端",安装过程就不赘述了,一直"下一步"即可. 电脑常识 安装完毕后,可以在桌面上看到米聊的快捷方式,其图标

AngularJS学习笔记--002--Angular JS路由插件ui.router源码解析

路由(route),几乎所有的MVC(VM)框架都应该具有的特性,因为它是前端构建单页面应用(SPA)必不可少的组成部分. 那么,对于angular而言,它自然也有内置的路由模块:叫做ngRoute. 不过,大家很少用它,因为它的功能太有限,往往不能满足开发需求!! 于是,一个基于ngRoute开发的第三方路由模块,叫做ui.router,受到了大家的"追捧". ngRoute vs ui.router 首先,无论是使用哪种路由,作为框架额外的附加功能,它们都将以模块依赖的形式被引入,

Angular2学习笔记——详解路由器模型(Router)_AngularJS

Angular2以组件化的视角来看待web应用,使用Angular2开发的web应用,就是一棵组件树.组件大致分为两类:一类是如list.table这种通放之四海而皆准的通用组件,一类是专为业务开发的业务组件.实际开发中大部分时间我们都需要处理业务组件.对于SPA应用来说,一个通用的问题就是如何控制页面的切换,解决这个问题的通用方法就是利用路由器来实现. 路由配置 现在我们先撇开Angular2来看看通用的路由器模型.通常来讲SPA应用需要路由配置信息: [ { path: '', pathMa

node.js学习笔记(19) express路由

上一篇笔记中,我们已经使用express-generator创建过express项目.在项目的目录结构中其中一个目录就是routes. 路由是由一个 URI.HTTP 请求(GET.POST等)和若干个回调函数组成. app.METHOD(path, [callback...], callback) - app是express的实例 - METHOD是http的方法,post.get.put.delete...... - path是http请求的URI - callback是当路由匹配时要执行的

ZeroMQ的模式-Requset-Reply

我们先来看看第一种模式:Request-Reply Pattern. 请求应答模式. Request-Reply这个名字很直白,口语点说就是一问一答.可以使同步的遵循请求序的一问一答,也可以是异步的不按请求序的一问一答:其中也可以包含各种不同的路由策略--让谁来回答.zeromq定义的为这个模式服务的socket有:ZMQ_REQ, ZMQ_REP, ZMQ_ROUTER以及ZMQ_DEALER. 用他们进行合理的组合,就可以实现现实世界中各种不同的请求应答模式. 分别来看: ZMQ_REQ Z

CentOS上安装Node.js和mongodb笔记

  CentOS上安装Node.js和mongodb笔记        这篇文章主要介绍了CentOS上安装Node.js和mongodb笔记,本文讲解了Python安装.Node.js安装.npm安装.mongodb驱动安装.mongodb数据库操作测试代码等内容,需要的朋友可以参考下 之前听说过Node.js,只是知道它可以应用于服务器端,但是对很多具体的东西并不了解.今天在QCon上听了袁锋的分享<Node.js脱离了浏览器的Javascript>之后,顿时有了想立刻试一下的冲动. No