虽然Redis有订阅功能,但是订阅功能是实时的,过了这个点,就接收不到消息了。

同时,如果订阅的客户端因为某些特殊原因shutdown了,那也就找不回未处理完整的订阅事件了。

但好在,Redis还有一个消息队列,通过消息队列,我们不仅可以把发布提交的更快速(发布会遍历所有订阅者,并通知到所有订阅者),又可能不用担心订阅者遗漏掉发生过异常的通知。

我将在后续随笔通过swoole,phpredis,yii三者来协调订阅者,邮局,发布者角色。

PUBLISH 命令的实际实现由 pubsubPublishMessage 函数完成,它的完整定义如下:

// 发送消息 
  int pubsubPublishMessage(robj *channel, robj *message) { 
  int receivers = 0; 
  struct dictEntry *de; 
  listNode *ln; 
  listIter li; 
  /* Send to clients listening for that channel */ 
  // 向所有频道的订阅者发送消息 
  de = dictFind(server.pubsub_channels,channel); 
  if (de) { 
  list *list = dictGetVal(de); // 取出所有订阅者 
  listNode *ln; 
  listIter li; 
  // 遍历所有订阅者, 向它们发送消息 
  listRewind(list,&li); 
  while ((ln = listNext(&li)) != NULL) { 
  redisClient *c = ln->value; 
  addReply(c,shared.mbulkhdr[3]); 
  addReply(c,shared.messagebulk); 
  addReplyBulk(c,channel); // 打印频道名 
  addReplyBulk(c,message); // 打印消息 
  receivers++; // 更新接收者数量 
  } 
  } 
  /* Send to clients listening to matching channels */ 
  // 向所有被匹配模式的订阅者发送消息 
  if (listLength(server.pubsub_patterns)) { 
  listRewind(server.pubsub_patterns,&li); // 取出所有模式 
  channel = getDecodedObject(channel); 
  while ((ln = listNext(&li)) != NULL) { 
  pubsubPattern *pat = ln->value; // 取出模式 
  // 如果模式和 channel 匹配的话 
  // 向这个模式的订阅者发送消息 
  if (stringmatchlen((char*)pat->pattern->ptr, 
  sdslen(pat->pattern->ptr), 
  (char*)channel->ptr, 
  sdslen(channel->ptr),0)) { 
  addReply(pat->client,shared.mbulkhdr[4]); 
  addReply(pat->client,shared.pmessagebulk); 
  addReplyBulk(pat->client,pat->pattern); // 打印被匹配的模式 
  addReplyBulk(pat->client,channel); // 打印频道名 
  addReplyBulk(pat->client,message); // 打印消息 
  receivers++; // 更新接收者数量 
  } 
  } 
  decrRefCount(channel); // 释放用过的 channel 
  } 
  return receivers; // 返回接收者数量 
  }

Redis 实现高效不遗漏的事件封装的更多相关文章

  1. javascript通用事件封装

    随着最近几年Html5的兴起,越来越多的应用采用html5进行实现,一个优秀的网页应用不但需要美观简洁的UI界面,更需要一个良好的交互.网页应用大部分的交互需要用javascript事件进行实现.虽然 ...

  2. js移动端tap事件封装

    这几天做项目,发现移动端需要触摸事件,而click肯定是不行的,于是我对tap事件封装进行了搜索,找到了一篇文章,原文地址如下:http://www.jb51.net/article/50663.ht ...

  3. 对redis客户端jedis2.8.0的进一步封装

    jedis2.8.0的进一步封装: 1.序列化存储对象 2.结合spring,创建redis连接池 3.提供了基础的单个实体操作,有序list操作和一对多关系list的操作,对list提供了分页的封装 ...

  4. 浏览器兼容——DOM事件封装函数

    //封装函数var eventUtil={    //添加事件    addHandler:function(element,type,handler){        if(element.addE ...

  5. 原生JS跨浏览器事件封装处理

    引子:用javascript给元素绑定事件,我们可以用addEventListener这个方法,然而这个方法有兼容问题,比如在IE浏览器上面就无效,在IE上面要用attachEvent这个方法 一.a ...

  6. EXT.NET高效开发(二)——封装函数

    在上一篇<EXT.NET高效开发(一)--概述>中,大致的介绍了一下EXT.NET.那么本篇就要继续完成未完成的事业了.说到高效开发,那就是八仙过海各显神通.比如使用代码生成器,这点大家可 ...

  7. 在JS事件封装时,addEventListener()方法的this问题

    最近在写js的类库,模仿的是jquery的编程风格,当封装到事件监听的时候发现遇到了一个问题,代码是这样的: 上面是封装的一个事件委托的代码,我以为上面的封装跟普通的事件监听一样简单,结果我在调用时发 ...

  8. Windows 下Redis的部署 及key 过期事件

    window下Redis部署,下载安装完成之后,进入到redis目录: 1.修改配置文件redis.windows.service.conf配置密码 requirepass myRedis (注意在R ...

  9. springboot redis 监听过期key值事件

    redis 中的key值过期后,触发通知事件 1.创建springboot工程,创建监听类 maven配置 <dependencies> <dependency> <gr ...

随机推荐

  1. magento转移服务器和magento建立多站点总结

    magento转移服务器和magento建立多站点总结第一. 我们首先要做的就是把服务器上的magento转移到本地上来.详细步骤:1. 直接用magento的备份系统把网上数据库备份.如图:2. 数 ...

  2. Push推送原理

    Push 的工作机制 APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器. 推送可以分为三个阶段. 第一阶段:.net应用程 ...

  3. vcf_filter.py

    pyvcf 中带的一个工具 比其他工具用着好些 其他filter我很信不过~~  自己写的功能又很有限 所以转投vcf_filter.py啦 Filtering a VCF file based on ...

  4. editplus查找替换的正则表达式应用

    表达式        说明\t        制表符.\n        新行..        匹配任意字符.|        匹配表达式左边和右边的字符. 例如, "ab|bc" ...

  5. SAP自定义打印机纸张

    1 执行Spad,->点击"完全管理"->点击"设备类型" 2 点击"页格式" 3 新增两个页格式,  点击 更改->创建 ...

  6. 38. Count and Say

    The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, 1211, 111221 ...

  7. ZOJ 1007 Numerical Summation of a Series

    原题链接 题目大意:x的取值从0.000到2.000,输出每个x对应的y(x)的值 解法:参考了这篇日志http://www.cnblogs.com/godhand/archive/2010/04/2 ...

  8. 软件工程课程作业(二)--四则运算2改进版(c++)

    题目要求: 1.避免题目重复 2.可定制(数量/打印方式) 3.可以控制下列参数 (1)是否有乘除法 (2)是否有括号 (3)数值范围 (4)加减有无负数 (5)除法有无余数 关键设计思想: oper ...

  9. Radiobutton编辑

    package com.example.yuekao3; import java.util.ArrayList;import java.util.List; import com.baidu.farm ...

  10. hdu2546 饭卡    01背包

    link:http://acm.hdu.edu.cn/showproblem.php?pid=2546 也算一个贪心的想法吧. 先把总钱数减去5,再把价值最大的挑出来.然后用01背包.最终买下挑出来的 ...