php ZeroMQ 的使用
1、Request-Reply
2、Publisher-Subscriber
3、Parallel Pipeline

客户端和服务端都可以是 1:N 的模型。通常把 1 认为是服务端,N 认为是客户端 。ZMQ可以很好的支持路由功能(实现路由功能的组件叫作 Device),把 1:N 扩展为N:M(只需要加入若干路由节点)。
<?php
//创建一个新的套接字上下文
$context = new ZMQContext(); //创建一个ZMQ响应套接字
$rep = new ZMQSocket($context, ZMQ::SOCKET_REP); //绑定端口
$rep->bind("tcp://127.0.0.1:6666"); while(true) {
//循环处理消息 //获取消息
$req = $rep->recv();
echo "Received Message: {$req} \r\n"; sleep(1); //向客户端发送消息
$rep->send('World');
}
client.php代码如下:
<?php
//创建一个新的套接字上下文
$context = new ZMQContext(); //创建一个ZMQ请求套接字
$req = new ZMQSocket($context, ZMQ::SOCKET_REQ); //连接到端口
$req->connect("tcp://127.0.0.1:6666"); for($ix = 0; $ix < 5; ++$ix) {
//发送请求
$req->send('Hello'); $reply = $req->recv(); echo "Received Reply: {$reply} \r\n";
}
需要注意如下几点:
1、服务端和客户端无论谁先启动,效果是相同的,这点不同于 Socket。 2、在服务端收到信息以前,程序是阻塞的,会一直等待客户端连接上来。 3、服务端收到信息以后,会send一个"World"给客户端。 值得注意的是一定是client连接上来以后,
send 消息给 Server,然后 Server 再 recv 然后响应 client,这种一问一答式的。
如果 Server 先 send,client 先 recv 是会报错的。 4、ZMQ通信通信单元是消息,他除了知道 Bytes 的大小,他并不关心的消息格式。
因此,你可以使用任何你觉得好用的数据格式。Xml、Protocol Buffers、Thrift、json等。 5、虽然可以使用 ZMQ 实现 HTTP 协议,但是,这绝不是它所擅长的。

<?php
//创建一个新的套接字上下文
$context = new ZMQContext(); //创建一个ZMQ发布套接字
$pub = new ZMQSocket($context, ZMQ::SOCKET_PUB); //绑定端口
$pub->bind("tcp://127.0.0.1:7777"); while(true) {
$typeArr = array('A', 'B', 'C', 'D');
$tmp = mt_rand(0, 3);
$type = $typeArr[$tmp];
$num = mt_rand(1, 9999); $update = sprintf('%s %04d', $type, $num); echo "Send Message: {$update} \r\n"; sleep(1); //向客户端发送消息
$pub->send($update);
}
client.php代码如下:
<?php
//创建一个新的套接字上下文
$context = new ZMQContext(); //创建一个ZMQ订阅套接字
$sub = new ZMQSocket($context, ZMQ::SOCKET_SUB); //连接到端口
$sub->connect("tcp://127.0.0.1:7777"); $filter = 'B';
//设置消息过滤器,只接收类型为'B'的消息
$sub->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, $filter); for($ix = 0; $ix < 50; ++$ix) {
$update = $sub->recv();
sscanf($update, '%s %d', $type, $num); echo "type: {$type} num: {$num} \r\n";
}
上述代码表示,Pub端不断的发送类型在(A,B,C,D)中的随机数$num,而Sub端通过设置消息过滤,只接收类型为B的消息,接收50次后就退出。
1、与Hello World不同的是,Socket的类型变成SOCKET_PUB和SOCKET_SUB类型。 2、客户端需要$sub->setSockOpt(ZMQ::SOCKOPT_SUBSCRIBE, $filter);
设置一个过滤值,相当于设定一个订阅频道,否则什么信息也收不到。 3、服务器端一直不断的广播中,如果中途有 Sub 端退出,并不影响他继续的广播,
当 Sub 再连接上来的时候,收到的就是后来发送的新的信息了。
这对比较晚加入的,或者是中途离开的订阅者,必然会丢失掉一部分信息,这是这个模式的一个问题。 4、但是,如果 Pub 中途离开,所有的 Sub 会阻塞住,等待 Pub 再上线的时候,会继续接受信息。

<?php
//创建一个新的套接字上下文
$context = new ZMQContext(); //创建一个ZMQ分发套接字
$sed = new ZMQSocket($context, ZMQ::SOCKET_PUSH); //绑定端口
$sed->bind("tcp://127.0.0.1:8881"); //统计从0到1000000累加数
$num = 1000000;
//分50步
$step = 50;
//每步大小
$size = $num / $step;
//开始大小
$start = 0;
//结束大小
$end = 0; //将任务分发给worker节点
for($ix = 1; $ix <= $step; ++$ix) {
$end = $start + $size; $data = sprintf('%d %d', $start, $end);
echo "start: {$start} end: {$end} \r\n";
$sed->send($data);
$start = $end;
}
worker.php代码如下:
<?php
//创建一个新的套接字上下文
$context = new ZMQContext(); $rev = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$rev->connect("tcp://127.0.0.1:8881"); $sed = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
$sed->connect("tcp://127.0.0.1:8882"); while(true) { //获取分发过来的数据
$data = $rev->recv();
sscanf($data, '%d %d', $start, $end); //计算累加和
$total = 0;
for($ix = $start; $ix < $end; ++$ix) {
$total += $ix;
} echo "worker start: {$start} end: {$end} total: {$total} \r\n";
//把计算的结果发送给result
$sed->send($total);
}
<?php
//创建一个新的套接字上下文
$context = new ZMQContext(); $rev = new ZMQSocket($context, ZMQ::SOCKET_PULL); $rev->bind("tcp://127.0.0.1:8882"); $step = 50; $total = 0;
for($ix = 1; $ix <= $step; ++$ix) { //接收worker计算后的结果
$result = $rev->recv();
//累加结果
$total += $result;
}
//输出最后的计算结果
echo "result: {$total} \r\n";
php ZeroMQ 的使用的更多相关文章
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
- ZeroMQ:云时代极速消息通信库
ZeroMQ:云时代极速消息通信库(大规模|可扩展|低成本|高效率解决之道,大规模分布式|多线程应用程序|消息传递架构构建利器) [美]Pieter Hintjens(皮特.亨特金斯)著 卢涛 李 ...
- 以ZeroMQ谈消息中间件的设计【译文】
本文主要是探究学习比较流行的一款消息层是如何设计与实现的 ØMQ是一种消息传递系统,或者乐意的话可以称它为"面向消息的中间件".它在金融服务,游戏开发,嵌入式系统,学术研究和航空航 ...
- NetMQ(一):zeromq简介
ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...
- zeromq系列
ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...
- 消息队列之ZeroMQ(C++)
ZMQ是什么? 这是个类似于Socket的一系列接口,他跟Socket的区别是:普通 的socket是端到端的(1:1的关系),而ZMQ却是可以N:M 的关系,人们对BSD套接字的了解较多的是点对点的 ...
- ZeroMQ(ZMQ)函数接口英汉直译
找了好多地方都找不到ZMQ接口函数的中文文档,就厚着脸皮自己翻译了下.但因为作者本人涉世未深,翻译有错误的地方还请大家不吝赐教,在下感激不尽. 因为时间有限,只能一点一点翻译了. ZMQ接口文档的官方 ...
- ZeroMQ接口函数之 :zmq - 0MQ 轻量级消息传输内核
官方网址:http://api.zeromq.org/4-0:zmq zmq(7) 0MQ Manual - 0MQ/3.2.5 Name zmq – ØMQ 轻量级消息传输内核 Synopsis # ...
- ZeroMQ接口函数之 :zmq_bind - 绑定一个socket
ZeroMQ 官方地址 : http://api.zeromq.org/4-0:zmq-bind zmq_bind(3) ZMQ Manual - ZMQ/3.2.5 Name zmq_bind - ...
- ZeroMQ接口函数之 :zmq_close - 关闭ZMQ socket
ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_close zmq_close(3) ØMQ Manual - ØMQ/3.2.5 Name zmq_close ...
随机推荐
- Oracle中查询表的大小、表的占用情况和表空间的大小
有两种含义的表大小.一种是分配给一个表的物理空间数量,而不管空间是否被使用.可以这样查询获得字节数: select segment_name, bytes from user_segments whe ...
- tensorboard-sklearn数据-loss
记录sklearn数据训练时的loss值,用tensorboard可视化 三步骤:红字处 import tensorflow as tf from sklearn.datasets import lo ...
- 1_Utilities__bandwidthTest
使用三种模式(QUICK_MODE,RANGE_MODE,SHMOO_MODE),测试三种拷贝情况下的显存带宽(HostToDevice,DeviceToHost,DeviceToDevice) ▶ ...
- sqlserver查询---分配cpu等资源
数据库资源按需分配 https://www.cnblogs.com/i6first/p/4138365.html https://blog.csdn.net/kk185800961/article/d ...
- HTML5 Canvas ( 扩展context('2d') ) CanvasRenderingContext2D.prototype.你的方法名
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- HTML5 Canvas ( 图形的透明度和遮盖 ) globalAlpha, globalCompositeOperation
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- IE6部分兼容问题
border-style:dotted 点线 IE6不兼容 (除了solid以外,其它都有兼容问题,不完全一样) a IE6 不支持a以外的所有标签伪类,IE6以上版本支持所有标签的hover伪类. ...
- python内置函数 eval()、exec()以及complie()函数
1.eval函数 eval() 函数用来执行一个字符串表达式,并返回表达式的值. eval(expression[, globals[, locals]]) 参数 expression -- 表达式. ...
- MCI 录制指定格式音频
可先用其他格式转换软件转换一段0秒指定格式的音频,然后用mcisendstring(L"open xxx.avi alias abc",0,0,0)打开,在进行录音mcisends ...
- spring coud feign
1. 依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>sprin ...