tsingsun / yii2-messenger
为yii2 php框架提供的消息发送和广播工具
Requires
- php: >=5.6.0
- yiisoft/yii2: ~2.0.10
Requires (Dev)
- guzzlehttp/guzzle: ~6.0
- phpunit/phpunit: 4.8.*
- yiisoft/yii2-queue: ~2.0.0
- yiisoft/yii2-redis: ~2.0.6
- yiisoft/yii2-swiftmailer: ~2.0.0
Suggests
- guzzlehttp/guzzle: is used for http request in gateway
- yiisoft/yii2-queue: you can use this package to work with queue
- yiisoft/yii2-redis: you can use this package to work with queue base on redis
- yiisoft/yii2-swiftmailer: the package is used for mail channel
This package is not auto-updated.
Last update: 2024-09-29 02:58:44 UTC
README
消息是各个系统中常用的基础模块,本项目旨在实现消息的通用性。
在一个系统中,消息可以分为很多种,如短信消息、邮件消息、微信消息等。从基于协议的角度来看,短信有短信协议,邮件和微信都有各自的协议,如邮件的协议有RTF2312,微信我们可以认为它的接口协议就是通信协议,只是非国际标准。
从单一种协议的角度来看,短信具有多种服务商来支持,比如腾讯云、阿里云都有各自的接口来实现短信的发送。
基于这两种现实,可以对系统进行如下划分:通道(channel)和网关(gateway)这两个概念,通道对应消息协议,网关对应在某种协议下的服务接口。为什么不直接把通道称之为协议,主要是因为邮件实际上是由多种协议构成,希望能留一些扩展点。
在一些短信网关的实现上,还借鉴了easy-sms。这个库已经实现了现在主流的短信网关实现。
安装
通过 Composer 进行安装
如果您没有 Composer,您可以按照 getcomposer.org 上的说明进行安装。
然后,您可以使用以下命令安装此项目模板
composer require --prefer-dist tsingsun/yii2-messenger
消息格式
消息都继承自BaseMessage,在类中定义了一些通用属性,如to、content等,我们就具体消息进行展开
- 短信 - SmsMessage
- 邮件 - EmailMessage
邮件支持基础的信息定义
收件人写法可以有多种:to:string; to:["email",....];to:["email"=>"name",....]
- 其他说明
各种消息定义了基础的消息类针对特定的通道,实际业务中,还会再继承,如订单的短信通知,OrderSmsMessage等来针对特定的消息
- 模板支持
目前很多消息工具都支持模板化,短信的模板是依赖于网关定义,在配置文件中的templates中定义
'templates'=>[ 'verifyCode'=>'10085', ],
key值应该考虑为全局性的,因为后期会使用通用消息而非通道特定消息来进行多通道发送,因此同类型的模板名保持一致,以减轻转化工作
开始使用
消息类的使用提供组件调用,由于消息是相对较全局的概念,因此不同于module项目,Messenger模块表现为Yii->$app下的一级组件。需要配置在主项目下
'messenger'=>[ 'class'=>'yak\message\components\Dispatcher', 'channels'=>[ [ //短信通道 'class'=>'yak\message\components\channels\SmsChannel', //发送策略 'strategy'=>[ 'class'=>'yak\message\components\strategies\OrderStrategy', ], 'gateways'=>[ 'qcloud' ], 'gatewayProviders'=>[ //腾讯云 'qcloud'=>[ 'class'=> 'yak\message\components\gateways\QCloudSmsGateway', 'appId'=>'', 'appKey'=>'', 'sign'=>'', 'templates'=>[ 'verifyCode'=>'10085', ], ], ], ], [ //短信通道 'class'=>'yak\message\components\channels\EmailChannel', //发送策略 'strategy'=>[ 'class'=>'yak\message\components\strategies\OrderStrategy', ], 'gateways'=>[ 'swiftmailer' ], 'gatewayProviders'=>[ //swiftmailer 'swiftmailer'=>[ 'class'=> 'yak\message\components\gateways\SwiftmailerGateway', 'templates'=>[ //支持别名 'register'=>'@yak/message/views/layouts/email-register', ], ], ], ] ], ],
邮件的模板文件的全路径方式有控制器要求,一般采用别名方式
- 组件方式 - Messenger
$messenger = Yii->$app->get('messenger')->getMessenger(); // #messenger = Messenger::instance();//简写 //$msg....实例化 #messenger->message($msg)->send();
事件
消息的发送机制队列栈,并且存在多通道方式,因此在send方法中,并没有返回值供业务端。当需要进一步跟踪消息状态时,需要利用事件机制。提供了beforeSend、afterSend事件,这两个事件在单网关单消息发送过程中会触发。
//配置文件方式,callable 'on beforeSend'=>['classname','methodname'], //代码方式 /** @var Dispatcher $dispatcher */ $dispatcher = \Yii::$app->get('message'); $dispatcher->on(Dispatcher::EVENT_AFTER_SEND, function ($event) {....}); $dispatcher->on(Dispatcher::EVENT_BEFORE_SEND, function ($event) {....});
事件的event为[[SendEvent]实例,提供了不同的数据
- beforeSend
单条消息发送前触发,可以处理消息保存、规则验证等。
function onBeforeSend($event) { $gateway = $event->sender; $message = $event->message; //可以在发送前保存数据,将消息送达状态设计为false //消息保存时,需要注意保存时的去重 $id = saveMessage($message); $message->extra['id'] = $id; }
- afterSend
消息发送后触发,可以处理消息状态、异常日志等。
function onAfterSend($event) { $gateway = $event->sender; $message = $event->message; $result = $event->sendResult; if($result->status){ updateMessage($message->extra['id']) }else{ //某个网关发送异常日志 } }
网关的返回接收请求成功并不等于消息到达,这中间涉及到网关的系统边界,我们这边成功是指网关接收到消息的发送请求,并响应。
- sendError 当消息在每个通道中处理失败时,表示为该通道下的网关都发送失败,则触发该事件。
消息扩展及通道化 -- 待完善
消息持久化 -- 待设计与实现
发送策略
目前只是很简单的处理了顺序及随机策略,基于可扩展的策略配置,后期再考虑特定策略
队列处理
支持消息的发布与订阅端。可以在消息源端设定为将业务端消息推送入队列,而不是实际发送。这样业务端就成为发布者。订阅者从队列中接收消息,执行实际的消息处理及发送。
- 消息源配置 sendToQueue = true,这样就可以将消息转发至消息队列
- 消息队列处理后台: sendToQueue = false,这样就可以将消息交还给实际的处理Job
内置了基于Job的消息处理。基于Job的通道将消息都处理为SendMessageJob,由订阅端执行该任务。具体的实现支持为yii-queue 如果采用指定化消息,请自己实现消息的订阅。
其他通道
- 微信 -- 待实现
其他网关
- 各主流的短信网关,我们之前采用过的网关,融联云、移动
- 微信网关