nineinchinck 消息系统学习笔记

2016-11-19 08:14:54来源:CSDN作者:johnny_Nicolas人点击

第七城市

安装过程

  • Run php composer.phar require nineinchnick/yii2-nfy "dev-master" OR add to composer.json require section "nineinchnick/yii2-nfy": "dev-master"
  • 配置文件
$config = [    // .........    'aliases' => [        '@nineinchnick/nfy' => '@vendor/nineinchnick/yii2-nfy',    ],    'modules' => [        'nfy' => [            'class' => 'nineinchnick/nfy/Module',        ],    ],    'components' => [        'dbmq' => [            'class' => 'nineinchnick/nfy/components/DbQueue',            'id' => 'queue',            'label' => 'Notifications',            'timeout' => 30,        ],        'sysvmq' => [            'class' => 'nineinchnick/nfy/components/SysVQueue',            'id' => 'a',            'label' => 'IPC queue',        ],        'redismq' => [            'class' => 'nineinchnick/nfy/components/RedisQueue',            'id' => 'mq',            'label' => 'Redis queue',            'redis' => 'redis',        ],        // ..........    ],]
  • yii migrate --migrationPath=nfy.migrations(后面为我的migrate文件)
    • 在migrate之前,首先要指定我的user表, $userClass = 'backend/models/Account'; 不然会默认使用名为user的表,则不能创建数据库成功
    • migrate 命令执行完成之后,进入到数据里面将(nfy_messages的表的sender_id 和nfy_subscriptions subscriber_id 变成你的userId一致的类型,我这里是varchar(45))
    • 在这个nfy module里面找到models下面的dbMessage和dbSubscription类,将其rules里面验证(sender_id, subscriber_id 为整形的规则去掉,因为我的系统里面用的userId并不是integer)
    • migrate 完成之后,进入数据库,会看到三张表
      • nfy_messages的表,此表存放message的主体信息(body),queue_id(队列的Id号,由上面配置的信息,我们可以得到默认的id 为queue,这个我们可以自己指定),状态(status: available[这个状态下可以被receive], deleted[被receive之后就变成了这个状态],reserved,暂时没有研究这个状态),subscripted_id(这个玩意,是nfy_subsciptions的外键,决定那个subscription可以来读取这个message, 默认状态下是没有,也就是值如果指定subscriber_id则读取不到),sender_id(就是值消息的发送者)
      • nfy_subscriptions表,字面理解这个表为,表示一个用户(subcriber_id)监听哪些队列(queue_id)
      • nfy_subscitpion_categoried表,存放subcritpion与category的属性,一个subsciption可以有多个category

基本工作流程

基本概念: 消息系统的基本流程应该是,首先存放消息,放入数据库,在存放消息的通过指定一个或者一些属性,来决定这个消息谁可以来读;然后,其他用户在访问消息队列的时候便可以得到他可以读的消息;

在这个消息系统里面可能有稍微的不同,首先是由接收者subscibe了某几条队列(一个人监听一个queue需要创建一个subscription),并且指定好这个几条subcription的category,然后发送者在发送消息的通过指定category来决定将这个message发送给那几个subscription,最后接收者在receive message的时候,会收到发送者发送过来的消息

工作流程代码实现

// 这样往数据库里面存入一条 没有subscribe_id的message, 状态为availableYii::$app->dbmq->send('test');//在接收者这端使用下面命令,就可以接收这条数据Yii::$app->dbmq->receive();// 或者Yii::$app->dbmq->peek();// 上面两条代码都是接收无subcription_id的数据
// 我们可以subscribe 看成订阅这个动作,subcription看成是我们订阅的杂志// 接收者, subscibe 队列id为queue,cateogry为 ['test', 'admin'] 的subscriptionYii::$app->dbmq->subscribe(Yii::$app->user->getId, [    'test',    'admin',]);// 或者我们可以发送一些指定某个属性之后,只有特定人群可见的message/**  * 发送者:发送一条body 'this is test'的message  * 1. 通过指定category 决定subscribe哪个subscription的人可以接收到消息  * 2. 如果有十个人subscibe了category为['test','admin','project']的subscription,则在系统里面会生成11条message, 如果没有subscibe category为如下的subscription,者在系统里面只会生成一条message  */Yii::$app->dbmq->send('this is test', [    'test',    'admin',    'project',]);// 接收者指定subscribr_id来接收消息,在接收到消息之后,会将消息的状态置为deletedYii::$app->dbmq->receive(Yii::$app->user->getId());

小结:

接收者要想接收到消息

  • subscribe的subsciber_id是接收者本人
  • subscribe的queue_id要对
  • subscribe的category要对
  • message 不能超时,status不能变成deleted

初步评估

优点

  • 同时支持mysql 和 redis
  • 通过这种订阅者模式
    • 有订阅者,就给他创建相对应的消息副本,没有就不用创建相对应的消息副本,相对比较节约空间,对数据的操作也会较少(也许这里再进一步优化)
    • 通过queue_id和category来控制消息接收人,作了比较好的分组,易于我们实现较为复杂的消息系统
  • 同时支持ajax polling 和 websocket push, 并且通过插件作好了封装

缺点:

  • 缺少文档说明,功能全靠查看源码摸索
  • 在验证的时候,指定了sender_id和subscriber_id为整形(数据库里面这两个字段也都是整形的),导致一些userId为非整形的系统,需要修改源码,调试程序
  • 模式相对复杂,不适用于简单的消息系统
  • 要根据他的原理,设计一套适用于我们系统的规则,比较麻烦
  • 没有设计消息的优先级
  • 拿到数据之后调用浏览器的消息提示,我们可以作自己的消息提示
  • notification支持firefox, chrome, safari
  • 被读取过的Message就会变成deleted,会导致我没有查看过的消息,下次也看不到了,所以可能基于这个消息之外还需要一个方法来记录没有被点击过的消息
  • 消息超时机制实测有问题(既超时的消息还是会被显示出来)
第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台