ZMQ的学习和研究

ZMQ 的三个基本模型

ZMQ 提供了三个基本的通信模型,分别是'Request-Reply','Publisher-Subscriber','Parallel Pipeline',我们从这三种模式一窥 ZMQ 的究竟

Request-Reply 模式

由 Client 发起请求,并等待 Server 回应请求。请求端发送一个简单的 hello,服务端则回应一个 world。
请求端和服务端都可以是 1:N 的模型。
通常把 1 认为是 Server ,N 认为是 Client 。
ZMQ 可以很好的支持路由功能(实现路由功能的组件叫作 Device),
把 1:N 扩展为N:M (只需要加入若干路由节点)。如图 1 所示:

cliet=>subroutine: 客户端
cliet1=>subroutine: 客户端
server=>subroutine: 服务端
hello=>operation: Hello
world=>operation: World

cliet(right)->hello(right)->server(right)->world(right)->cliet1

服务端代码:

$context = new ZMQContext (1);
// Socket to talk to clients
$responder = new ZMQSocket ($context, ZMQ::SOCKET_REP);
$responder->bind ("tcp://*:5555");
while(true) {
// Wait for next request from client
$request = $responder->recv ();
printf ("Received request: [%s]\n", $request);

// Do some 'work'
sleep (1);

// Send reply back to client
$responder->send ("World");
}

客户端代码:

$context = new ZMQContext ();
//  Socket to talk to server
echo "Connecting to hello world server...\n";
$requester = new ZMQSocket ($context, ZMQ::SOCKET_REQ);
$requester->connect ("tcp://localhost:5555");
for($request_nbr = 0; $request_nbr != 10; $request_nbr++) {
    printf ("Sending request %d...\n", $request_nbr);
    $requester->send ("Hello");
    $reply = $requester->recv ();
    printf ("Received reply %d: [%s]\n", $request_nbr, $reply);

}

从以上的过程,我们可以了解到使用 ZMQ 写基本的程序的方法,需要注意的是: 1. 服务端和客户端无论谁先启动,效果是相同的,这点不同于 Socket。 2. 在服务端收到信息以前,程序是阻塞的,会一直等待客户端连接上来。 3. 服务端收到信息以后,会 send 一个“World”给客户端。值得注意的是一定是 client 连接上来以后,send 消息给 Server,然后 Server 再 rev 然后响应 client,这种一问一答式的。如果 Server 先 send,client 先 rev 是会报错的。 4. ZMQ 通信通信单元是消息,他除了知道 Bytes 的大小,他并不关心的消息格式。因此,你可以使用任何你觉得好用的数据格式。Xml、Protocol Buffers、Thrift、json 等等。 5. 虽然可以使用 ZMQ 实现 HTTP 协议,但是,这绝不是他所擅长的。

Publish-subscribe 模式

(dist/images/logo.png "Title")

cliet=>subroutine: 客户端
cliet1=>subroutine: 客户端
server=>subroutine: 服务端
hello=>operation: Hello
world=>operation: World

cliet(right)->hello(right)->server(right)->world(right)->cliet1