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 ...
随机推荐
- 关于input=file的用法
<input type="file"/>这个东西是用来上传图片用的. 1,但是存在一下问题但是在在各个浏览器下的显示是不一样的 IE下: IE之外的浏览器: 2.如果不 ...
- Django中间件执行流程
中间件函数是 django 框架为我们预留的函数接口, 让我们可以干预请求和应答的过程 1. 获取浏览器端的IP地址: 使用 request.META[‘REMOTE_ADDR’] 2. 使用中间件 ...
- ECCV 2018 | Bi-Real net:超XNOR-net 10%的ImageNet分类精度
这项工作由香港科技大学,腾讯 AI lab,以及华中科技大学合作完成,目的是提升二值化卷积神经网络(1-bit CNN)的精度.虽然 1-bit CNN 压缩程度高,但是其当前在大数据集上的分类精度与 ...
- (c#) 销毁资源和释放内存
0. 什么是资源? .NET 框架中如何访问资源? 所谓的资源就是程序中可利用的数据,譬如:字符串.图片和任何二进制数据,包括任何类型的文件. 在面向对象的环境中,每一个类型都标识为某些程序所用的资源 ...
- Mysql主从同步在线实施步骤【适合大数据库从库配置】
Mysql主从同步在线实施步骤[适合大数据库从库配置] MySQL的主从搭建大家有很多种方式,传统的mysqldump方式是很多人的选择之一,但比较适合在新实例中实施,对于较大的数据库则存在停机等不可 ...
- uva-639-枚举
题意: 象棋里的車可以吃横竖的車,题目加了一个墙,用于阻断攻击,问4x4的棋盘最多可以放多少只車, 思路:枚举每一个点,2^16次方种情况 #include<stdio.h> #inclu ...
- systemctl管理系统配置、服务
systemctl daemon-reload \&& systemctl enable docker \&& systemctl start docker \& ...
- 25. LiveBos调用class实例
var v= ABS_LOADBEAN('com.apex.mmsqljdbc.TestJDBC');var date=ABS_SQLVALUE("select to_char(?,'yyy ...
- 反射(hasattr , getattr, setattr) 输入的字符串用来运行程序
当用户输入字符串时,不能够用来运行程序 1.使用 hasattr 找出输入的字符串是否在程序内 2.使用 getattr 返回找出字符串对应的函数的内存地址或者变量 3. 使用setattr 添加新的 ...
- PuTTY免输密码自动登录Linux
1.使用PuTTY安装目录里的puttygen.exe工具.先点“生成(Generate)”,然后随意移动鼠标直到进度条填满,即可生成密钥 公钥部分:把上边那一段文字全选->复制备用.(不要点击 ...