版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
作为教育软件,学生与老师与家长的实时互动变得尤为重要,打算给系统加入一个消息中间件,用于实时通知老师学生正在发生的行为。
准备阶段
服务器:mac (因为是先在本机进行实验性测试)
php框架: Yaf
MQ: RabbitMQ3.7.7
Publisher: php 7.2.2
consumer: web
为什么使用RabbitMq而不是ActiveMq或者RocketMq?
- 首先,从业务上来讲,我并不要求消息的100%接受率,并且,我需要结合php开发,RabbitMq相较RocketMq,延迟较低(微妙级)。至于ActiveMq,貌似问题较多。RabbitMq对各种语言的支持较好,所以选择RabbitMq。
php方面则是使用php-amqplib这个第三方库用于发送消息,在yaf下使用composer安装即可。
前端使用库 stomp.js,因为官方文档也将到了这个库,并给出了示例。
安装RabbitMq
下载地址,去官网下载与自己服务器响应的tar包,解压即可。
将安装目录下的sbin配置到环境变量中,方便自己操作。
启动服务
rabbitmq-server
- 注意:会提示timeout,将提示中的hostname加入
/etc/hosts
中再次尝试
使用rabbitmq-plugins开启扩展
// 这个是为了开始webui,方便查看和管理,默认用户名和密码都是 guest
rabbitmq-plugins enable rabbitmq_management
// 开启stomp支持,为了web端进行消费
rabbitmq-plugins enable rabbitmq_web_stomp
重启server,查看启动状态,加载了5个plugins。
访问webui 【http://localhost:15672/#/】
至此,MQ测试服务搭建成功。
yaf中php相关代码。
- composer 自己加入,执行
composer require php-amqplib/php-amqplib
- 在
html/index.php
中引入autoload
require_once __DIR__.'/../vendor/autoload.php';
- 在测试的控制器中编写publisher
<?php
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
class IndexController extends Yaf_Controller_Abstract
{
public function testAction()
{
$exchange = 'router';
$queue = 'msgs';
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest', '/');
$channel = $connection->channel();
$channel->queue_declare($queue, false, true, false, false);
$channel->exchange_declare($exchange, 'direct', false, true, false);
$channel->queue_bind($queue, $exchange);
$message = new AMQPMessage("hello", array('content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT));
$channel->basic_publish($message, $exchange);
return false;
}
}
编写web端用于消费
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src='./stomp.js'></script>
</head>
<body>
<script>
var ws = new WebSocket('ws://127.0.0.1:15674/ws');
var client = Stomp.over(ws);
var on_connect = function() {
console.log('connected');
client.subscribe('/queue/msgs', function (frame){
console.log(frame)
});
};
var on_error = function() {
console.log('error');
};
client.connect('guest', 'guest', on_connect, on_error, '/');
</script>
</body>
</html>