ZeroMQ —— The Intelligent Transport Layer (智能的传输层封装)
1,与其说它可嵌入的网络库,不如说是一个并发的socket框架
2,集群上使用比TCP快速
3,消息通过inpro,IPC,TCP以及广播方式传输
4,通过fanout(扇出),pubsub,pipeline,request-reply实现多对多通信
5,异步IO
6,活跃社区支持
7,拥有30多种语言的扩展库
8,支持window,linux,os x等系统
9,LGPL许可
安装过程如下:
下载源码zeromq-3.2.2.tar.gz编译安装,然后安装php扩展
git clone git://github.com/mkoppanen/php-zmq.git phpize ./configure --with-php-config=/root/bin/php-config make && make install
编辑php.ini 添加 extension=zmq.so
编程参考手册 http://php.zero.mq
这里有大量程序示例可供参考https://github.com/imatix/zguide
A,request/reply
写一个服务端 server.php
<?php /* * Hello World server * Binds REP socket to tcp://*:5555 * Expects "Hello" from client, replies with "World" * @author Ian Barber <ian(dot)barber(at)gmail(dot)com> */ $context = new ZMQContext(1); $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"); }
写一个客户端client.php
<?php //allocate a new context $context = new ZMQContext(); //create a new socket $queue = $context->getSocket(ZMQ::SOCKET_REQ,"mysock"); //connect the server $queue->connect("tcp://127.0.0.1:5555"); //send and receive message var_dump($queue->send("Hello, using mysock")->recv()); ?>
一个简单的服务应答就搭建好了,支持并发。可以开启多个client.php去连接服务器端测试。这是简单的request-reply,下面看看如何实现pub/sub(发布/订阅)
B,publish/subscribe
发布端 publisher.php
<?php // Prepare our context and publisher $context = new ZMQContext(); $publisher = $context->getSocket(ZMQ::SOCKET_PUB); $publisher->bind("tcp://127.0.0.1:5556"); while (true) { $filter = mt_rand(1, 9); // Send message to all subscribers $update = sprintf ("%d Hello%d", $filter, $filter); $publisher->send($update); usleep(100000); } ?>
订阅端 subscriber.php
<?php $context = new ZMQContext(); // Socket to talk to server echo "Subscribe message from server...", PHP_EOL; $subscriber = new ZMQSocket($context, ZMQ::SOCKET_SUB); $subscriber->connect("tcp://127.0.0.1:5556"); // Subscribe to 1 or other channel $filter = $_SERVER['argc'] > 1 ? $_SERVER['argv'][1] : "1"; $subscriber->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, $filter); // Process 100 updates $total_temp = 0; while(true) { $string = $subscriber->recv(); sscanf ($string, "%d %s", $filter, $msg); echo "$filter recv $msg\n"; } ?>
运行一个publisher.php端,然后启动多个subscriber.php
a, php subscriber.php 1 (能收到$filter=1的所有消息)
b, php subscriber.php 1 (能收到$filter=1的所有消息)
c, php subscriber.php 3 (能收到$filter=3的所有消息)