利用redis自制幻灯片弹幕
前段时间赶项目,忙结婚,各大技术平台都没时间上,不过还是抽出点时间为自己的婚礼做了一点小玩具,今天我就来给大家分享一下。
先来看一下效果


这个项目是基于微信个人订阅号的,订阅号的开发在此我就不再赘述了。
基本开发思路是,服务器接收到用户文本信息,用正则匹配一下然后去掉前面的cg#(这一步其实可有可无,不过为了区分其他的指令而加上),然后存进服务器。本地用浏览器跑一个轮播图,然后拿到弹幕信息就可以在浏览器播放了。
这里有2个关键点:
1、本地如何拿到弹幕信息?两台物理机器如何实时获取信息?这里的信息延迟我要求不能超过1s。这里我找到有两个方案,A 本地设置定时器直接请求远程服务器拉取弹幕信息。B 本地与远程服务器建立一个socket长连接,服务器主动写数据。
2、这个场景交互比较频繁,IO相对比较密集(婚礼上并发可能会高达100+),存数据库的话压力会比较大,如果挂掉了本少爷的脸也挂不住了-_-||
好,接着来一个一个的解决,先从技术选型开始。
1、如果数据库扛不住,那么我不存数据库,直接存缓存行得通吗?弹幕信息带有时序性的属性,redis自带队列数据结构,这很适合,redis对外宣称的并发数为3-5w,刚好之前被推荐买了一本redis实战,也看完了,就用来实践一下。服务器拿到弹幕信息后存进队列
/**
* [saveInfo description]
* @param object $postObj 微信XML实体
* @return [type] [description]
*/
private function saveInfo($postObj) {
// 数据处理
$openid = $postObj->FromUserName;
$content = preg_replace("/^(cg#){1}/i", "", $postObj->Content); // 准备存入队列的json数据
$value = array(
"openid" => $openid,
"content" => $content,
"time" => strval(microtime())
);
$json = json_encode($value); // 把用户的弹幕内容存进队列中
$result = $this->lpush(BARRAGE_KEY, $json); return $result?$json:false;
}
(原本已经调了用户接口,打算搞抽奖的,但我没有搞企业服务号,所以后面就去掉了这一部分了,就是用fromUser这个openID去获取用户nickname,headurl等信息)
2、好了,存好的弹幕信息,就差本地去拿了,获取弹幕信息的方式影响到整个程序能否成功运行,这里我想到的两个方案不知孰优孰劣,唯有一试。
首先尝试定时获取,写一个js定时器去请求远程服务器,进而拉取弹幕信息。方法甫一运行,本地就卡的不要不要的,轮播图也变成了幻灯片,毋论接收弹幕了。另外,这里还会有浏览器跨域的问题存在。
然后,查资料得知,redis本身是依赖于socket运行的,还有自带现成发布订阅功能(publish和subscribe),跟我的需求完美契合。所以我重点写好建立连接和接收数据的回调就好了。
建立连接的代码(这个我为了方便,是用php指令来运行脚本的):
/**
* [pullBarrages 拉取腾讯云中最新的弹幕]
*/
public function pullBarrages() {
try {
set_time_limit(0);
ini_set("default_socket_timeout", -1);
ignore_user_abort(TRUE);
// 首先同步一次弹幕
$this->synchronizeBarrages();
// 订阅新的弹幕频道并保存
$this->subscribe(array(BARRAGE_CHANNEL), array($this, "saveBarrage"));
} catch (Exception $e) {
// 连接超时出现异常时重新建立长连接
$host = "IP";
$port = ;
$this->redis = new RedisCache();
$this->redis->connect($host, $port);
// 检查同步远程主机的弹幕同步情况
$this->synchronizeBarrages();
// 重新调用长连接订阅方法
$this->pullBarrages();
}
}
这里我写了一段监听异常的代码,因为连接之后过了大概60秒就自动断开,所以我捕捉到异常就重新建立连接并且确认是否有没有拉取到的弹幕信息。不清楚是PHP对socket的支持不太好还是我的PHP环境的原因(我的PHP用的是集成环境),这里我没有太多时间去深究,如果有知道的大牛请告诉我,谢谢~
接收到数据之后的回调函数:
/**
* [saveBarrages description]
* @param object $redis redis对象
* @param string $channel 订阅的频道
* @param string $barrage 频道订阅返回的弹幕信息
* @return Boolean 存储结果
*/
public function saveBarrage($redis, $channel, $barrage) {
$localRedis = new RedisCache();
$localRedis->connect("127.0.0.1", 6379); $result = $localRedis->lpush(BARRAGE_KEY, $barrage);
if ($result) {
echo "barrage save success!" . PHP_EOL;
}else {
echo "barrage save fail!" . PHP_EOL;
}
echo date("Y-m-d H:i:s") . PHP_EOL;
}
本地拿到了服务器的弹幕信息,剩下的就随便怎么玩都可以了,拿到弹幕信息大概是秒达的感觉。前端浏览器现在也是有websocket,但是我不会用,所以选择了在浏览器设置一个定时器去请求本地环境的弹幕数据,间隔自己定就可以了(关于前端的东西不细讲,后端做前端的诀窍就是找插件,哈哈)。
还有一点,就是我为了方便写代码,把redis对象省略了,用到了__call方法来调用,这个在我之前的博客中提到过。
断断续续的完成这篇博客,以上写的可能有点乱,抱歉。这次就分享这么多,下次有其他东西再来分享~~
2017.12.04编辑:
关于链接被断开,通过捕捉异常来重新连接redis的部分找到了比较好的解决办法了,自动断开连接是因为redis的subscribe方默认在60s内没有接收到信息的话,就会自动断开,只需要添加一行代码:
$redis->setOption(Redis::OPT_READ_TIMEOUT, -1);
让redis不超时就可以了。
利用redis自制幻灯片弹幕的更多相关文章
- 利用Redis解决Url过长的问题
做网站,接手别人的代码,发现url有时候会过长导致页面直接翻掉. 后来想了一下可以利用redis将太长的地方暂存,加载页面时获取即可. 存Redis: /// <summary> /// ...
- 利用Redis cache优化app查询速度实践
注意:本篇文章译自speeding up existing app with a redis cache,如需要转载请注明出处. 发现问题 在应用解决方法之前,我们需要对我们面对的问题有一个清晰的认识 ...
- [翻译]利用REDIS来搭建可靠分布式锁的提议
本系列都是翻译REDIS作者的博文 另外加上我自己的一点点理解 希望有问题大家一起讨论 http://antirez.com/news/77 原文地址 在利用REDIS做分布式锁时基本持有2种观点 ...
- 利用redis写webshell
redis和mongodb我之所见 最近自己在做一些个人的小创作.小项目,其中用到了mongodb和redis,最初可能对这二者没有深入的认识.都是所谓的“非关系型数据库”,有什么区别么? 实际上,在 ...
- 如何利用redis来进行分布式集群系统的限流设计
在很多高并发请求的情况下,我们经常需要对系统进行限流,而且需要对应用集群进行全局的限流,那么我们如何类实现呢. 我们可以利用redis的缓存来进行实现,并且结合mysql数据库一起,先来看一个流程图. ...
- 利用redis实现分布式锁知识点总结及相关改进
利用redis实现分布式锁知识点总结及相关改进 先上原文,本文只为总结及对相关内容的质疑并提出若干意见,原文内容更详细https://www.cnblogs.com/linjiqin/p/800383 ...
- 利用redis实现分布式锁
分布式锁一般有三种实现方式: 1. 数据库乐观锁: 2. 基于ZooKeeper的分布式锁: 3. 基于Redis的分布式锁: 这里大概说一下三种方式的优缺点,数据库乐观锁优点是实现简单,只需要for ...
- 利用Redis发布订阅完成tomcat集群下的消息通知
以下为个人想法,如果有说的不对的地方请各位大佬见谅! 这是博主的第一篇博客,可能排版以及一些描述有不合理的地方还请勿喷,希望大家尽可能的多给我这样的新人一些鼓励让我能在写博客的道路上走下去. 进入正题 ...
- Watchdogs利用Redis实施大规模挖矿,常见数据库蠕虫如何破?
背景 2月20日17时许,阿里云安全监测到一起大规模挖矿事件,判断为Watchdogs蠕虫导致,并在第一时间进行了应急处置. 该蠕虫短时间内即造成大量Linux主机沦陷,一方面是利用Redis未授权访 ...
随机推荐
- TableEdit UI_10
1.tableView的编辑的步骤: 1.让tableView处于编辑状态,(默认所有的cell都处于编辑状态,默认下的编辑样式是删除) 2.设置哪些cell可以编辑 3.设置编辑的样式(删除,插 ...
- 浅谈OC内存管理
一.基本原理 (一)为什么要进行内存管理. 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时,系统就会发出内存警告,这时需要回收一些不需要再继续使用的内存空 ...
- (NO.00001)iOS游戏SpeedBoy Lite成形记(十三)
游戏特效部分就先这样了,因为毕竟是Lite版本,而且是第一个App,所以咱们把主要精力放在游戏可玩逻辑上吧(虽然已经厚颜无耻的加了不少特效了). 说句题外话:游戏美工是独立开发者不可逾越的鸿沟,是无法 ...
- Android通过编译源代码提供系统服务-android学习之旅(85)
通过编译android4.1.2的源代码,添加一个FregServer的系统服务,以及一个服务代理FregClient 具体分为三部分,client,common,server,common中规定了c ...
- PHP 与搜索蜘蛛
本文移到:http://www.phpgay.com/Article/detail/classid/2/id/63.html
- 集群通信组件tribes之应用程序处理入口
Tribes为了更清晰更好地划分职责,它被设计成用IO层和应用层,IO层专心负责网络传输方面的逻辑处理,把接收到的数据往应用层传送,当然应用层发送的数据也是通过此IO层发送,数据传往应用层后必须要留一 ...
- 【一天一道LeetCode】#15 3Sum
一天一道LeetCode系列 (一)题目 Given an array S of n integers, are there elements a, b, c in S such that a + b ...
- Java泛型type体系
最近看开源代码,看到里面很多Java泛型,并且通过反射去获取泛型信息.如果说要看懂泛型代码,那还是比较容易,但是如果要自己利用泛型写成漂亮巧妙的框架,那必须对泛型有足够的了解.所以这两三天就不在不断地 ...
- EBS R12安装升级(FRESH)(三)
5 EBS R12.1.1安装后配置 5.1 新建patch文件夹 1 2 3 su - root mkdir /stage/patch chmod 777 /stage/patch 打补丁说明:随便 ...
- 2010-01-20 12:09 ubuntu下minicom的安装及使用
转http://hi.baidu.com/npugtawqdnbgqrq/item/106f805409b42813db163527 ubuntu下minicom的安装及使用 安装: sudo apt ...