Redis 实现高效不遗漏的事件封装
虽然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 实现高效不遗漏的事件封装的更多相关文章
- javascript通用事件封装
随着最近几年Html5的兴起,越来越多的应用采用html5进行实现,一个优秀的网页应用不但需要美观简洁的UI界面,更需要一个良好的交互.网页应用大部分的交互需要用javascript事件进行实现.虽然 ...
- js移动端tap事件封装
这几天做项目,发现移动端需要触摸事件,而click肯定是不行的,于是我对tap事件封装进行了搜索,找到了一篇文章,原文地址如下:http://www.jb51.net/article/50663.ht ...
- 对redis客户端jedis2.8.0的进一步封装
jedis2.8.0的进一步封装: 1.序列化存储对象 2.结合spring,创建redis连接池 3.提供了基础的单个实体操作,有序list操作和一对多关系list的操作,对list提供了分页的封装 ...
- 浏览器兼容——DOM事件封装函数
//封装函数var eventUtil={ //添加事件 addHandler:function(element,type,handler){ if(element.addE ...
- 原生JS跨浏览器事件封装处理
引子:用javascript给元素绑定事件,我们可以用addEventListener这个方法,然而这个方法有兼容问题,比如在IE浏览器上面就无效,在IE上面要用attachEvent这个方法 一.a ...
- EXT.NET高效开发(二)——封装函数
在上一篇<EXT.NET高效开发(一)--概述>中,大致的介绍了一下EXT.NET.那么本篇就要继续完成未完成的事业了.说到高效开发,那就是八仙过海各显神通.比如使用代码生成器,这点大家可 ...
- 在JS事件封装时,addEventListener()方法的this问题
最近在写js的类库,模仿的是jquery的编程风格,当封装到事件监听的时候发现遇到了一个问题,代码是这样的: 上面是封装的一个事件委托的代码,我以为上面的封装跟普通的事件监听一样简单,结果我在调用时发 ...
- Windows 下Redis的部署 及key 过期事件
window下Redis部署,下载安装完成之后,进入到redis目录: 1.修改配置文件redis.windows.service.conf配置密码 requirepass myRedis (注意在R ...
- springboot redis 监听过期key值事件
redis 中的key值过期后,触发通知事件 1.创建springboot工程,创建监听类 maven配置 <dependencies> <dependency> <gr ...
随机推荐
- 在SourceInsight中用快捷键打开文件所在的目录
创建一个Custom Command: ShellExecute open %d. 然后关联一个快捷键.
- CentOS6编译装载nbd模块
今天突然发现CentOS系统没有nbd模块,只能重新装下,下面记录下整个编译过程: 系统:CentOS6.5 内核:2.6.32-431.el6.x86_64 [root@localhost ~]# ...
- Java中生成随机字符的方法总结
package learnExercise; public class RandomCharacter { public static char getRandomCharacter(char ch1 ...
- 2014年IT互联网行业薪酬待遇
以下均为应届毕业生的起薪待遇: 一.民企 1. 百度 13k*14.6,special 14~17k*14.6 开发类 13K*14.6 (2014) 测试类.前端类 12K*14.6 (2014) ...
- UVa 11039 - Building designing
题目大意:n个绝对值各不相同的非0整数,选出尽量多的数,排成一个序列,使得正负号交替且绝对值递增. 分析:按照绝对值大小排一次序,然后扫描一次,顺便做个标记即可. #include<cstdio ...
- [转载] 动态链接库dll的 静态加载 与 动态加载
转载自:http://blog.csdn.net/youxin2012/article/details/11538491 dll 两种链接方式 : 动态链接和静态链接(链接亦称加载) 动态链接是 ...
- ANTLR3完全参考指南读书笔记[05]
前言 仅生成给出true/false的识别器是没有多大用处的,自然的就有在识别过程中遇到某一结构时执行一段代码.存储该结构中信息的想法. ANTLR提供了在文法中嵌入属性和动作超级混合“文法”,可以生 ...
- iOS平台网络类型检测
老大新增个需求,连接服务器时要区分内外网,需求理解了,现实很骨感啊,没办法,干. #import <Foundation/Foundation.h> /* 依赖于以下Framework S ...
- HDU 5957 Query on a graph
HDU 5957 Query on a graph 2016ACM/ICPC亚洲区沈阳站 题意 \(N(N \le 10^5)\)个点,\(N\)条边的连通图. 有\(M \le 10^5\)操作: ...
- PHP设置图片文件上传大小的具体实现方法
PHP默认的上传限定是最大2M,想上传超过此设定的文件,需要调整PHP.apache等的一些参数 我们简要介绍一下PHP文件上传涉及到的一些参数: •file_uploads :是否允许通过HTTP上 ...