• 消息系统
    • 目录结构
    • 使用指南
      • 1.创建你的消息实体类
      • 2.创建你的分发渠道
      • 3.创建消息
      • 4.消息处理
    • 最佳实践与提示

    消息系统

    version

    描述:一个系统里面通常都会有一些类似于站内信,用户私信等消息(Message),然后通过邮件,微信模板消息,短信等多种渠道(Sender)发送到对应用户上。消息系统这是解决这个问题。

    目录结构

    1. .
    2. ├── Controller
    3. ├── CronScript 计划任务脚本
    4. ├── Install
    5. ├── Libs 核心实现库
    6. ├── Messages 消息实体类
    7. ├── Model
    8. ├── Senders 发送渠道实现
    9. ├── Service 服务
    10. └── Uninstall

    使用指南

    1.创建你的消息实体类

    Message/Messages/ 目录下创建消息实体类,并继承 Message\Libs\Message 类,实现 createSender()

    1. use Message\Libs\Message;
    2. use Message\Model\MessageModel;
    3. class SimpleMessage extends Message {
    4. /**
    5. * SimpleMessage constructor.
    6. *
    7. * @param string $sender 发送人
    8. * @param string $receiver 接收人
    9. * @param string $content 消息ID
    10. */
    11. public function __construct($sender, $receiver, $content = '') {
    12. $this->setContent($content);
    13. $this->setType(MessageModel::TYPE_MESSAGE); //消息类型本系统没有过多的指定,默认提供 message 私信 和 remind 提醒这两种
    14. $this->setSender($sender); //发送人,可以是ID,也可以名字,由你的业务决定
    15. $this->setSenderType('member');//发送人的类型,可以为空,由你的业务决定
    16. $this->setReceiver($receiver); //接收人,可以是ID,也可以名字,由你的业务决定
    17. $this->setReceiverType('member'); //接收人的类型,可以为空,由你的业务决定
    18. $this->setTarget('1'); //消息源,如某某人点赞了一文章,则 Target 可能是文章ID,具体由你的业务决定
    19. $this->setTargetType('11');//消息源类型,如某某人点赞了一文章,则 Target 应该是文章类型名称,具体由你的业务决定
    20. }
    21. /**
    22. * 定义该消息的消息分发渠道
    23. *
    24. * @return array Senders数组
    25. */
    26. function createSender() {
    27. return [
    28. new SimpleSender(), //示例:发邮件
    29. new SimpleWxSender() //示例:发微信模板消息
    30. ];
    31. }
    32. }

    2.创建你的分发渠道

    Message/Senders/ 目录下创建消息实体类,并继承 Message\Libs\Sender 类,实现 doSend()

    示例:SimpleSender:

    1. class SimpleSender extends Sender {
    2. /**
    3. * 发送消息操作
    4. *
    5. * @param Message $message
    6. * @return boolean
    7. */
    8. function doSend(Message $message) {
    9. echo 'simple send => ' . $message->getContent() . '<br>';
    10. return true;
    11. }
    12. }

    3.创建消息

    使用 Message\Service\MessageService::createMessage($msg) 添加消息

    1. use Message\Service\MessageService;
    2. class TestController extends AdminBase {
    3. //发送信息
    4. function pushMessage() {
    5. $sender = 'jayin';
    6. $receiver = 'admin';
    7. $content = '用户 ' . $sender . ' 对用户 ' . $receiver . ' 说:' . '你好,这是推送 at ' . date('Y-m-d H:i:s');
    8. $msg = new SimpleMessage($sender, $receiver, $content);
    9. MessageService::createMessage($msg);
    10. }
    11. }

    4.消息处理

    使用 Message\Service\MessageService::handleMessage($msg_id) 处理(发送)消息

    4.1 手动处理一条消息

    1. use Message\Service\MessageService;
    2. class TestController extends AdminBase {
    3. //处理信息
    4. function handleMessage() {
    5. //取出未处理的消息,进行处理
    6. $messages = D('Message/Message')->where(['process_status' => MessageModel::PROCESS_STATUS_UNPROCESS])->field('id')->select();
    7. foreach ($messages as $index => $message) {
    8. MessageService::handleMessage($message['id']);
    9. }
    10. }
    11. }

    4.2 或者你可以添加计划任务,Message/CronScript/HandleMessage,建议每隔1分钟处理一次。

    最佳实践与提示

    1. 有多少不同类型的消息就建多少种 Message
    2. 有多少个消息分发渠道就建多少种 Sender
    3. 其实 Sender 相当于一个事件处理器(Handler),不要认为只能用来发消息(模板消息,短信等)
    4. Message 里 setContent(), setReceiver(), setTarget() 都不是必须,只是传入对应的参数方便 Sender 中自由的根据消息的来源信息自由修改发送内容