监控阮一峰老师的blog
引言
阮一峰大家基本都认识,很厉害的一个人,经济学博士,文章写得很棒,知识面很广泛,计算机、算法、英语、文采,这是能想到的他的一些标签,他的博客应该算是最受欢迎的博客之一了。
我经常回去看他的博客,但有时候时间长了,再次去看,发现他已经有好几篇新文章了,我就在想,能不能自己写个程序,监控的他博客,当他有新文章的时候,第一时间推送给我。
思路
他的博客中有一个feed,是一个返回xml格式文档的接口,这个接口是最新的文章列表,总共15篇,可以通过监控这个接口中前几篇文章列表的变化来间接的检测他的文章更新,如果有新的文章马上给我的邮箱发送邮件,这样我就可以尽可能早的get到阮老师的最新文章了。
这是设计思路图:

首先就是rss解析了,这个使用php的原生函数simplexml_load_string得到一个解析之后的SimpleXMLElement对象,通过该对象可以很轻松的获取到阮老师更新的前几篇文章。然后和redis中的已发送文章列表集合作对比,如果有新的更新,将更新的信息发送给UDPserver,让UDPserver去发送邮件给用户列表。检测程序循环执行,每10分钟跑一次。
开始编码
有了思路编码就很快了(这里其实优化了好几次,刚开始的时候思路也没有这么明了,边做边改,当然了,还是要慢慢锻炼,开始之前尽可能多的完善思路)。
使用PHP依赖管理利器——Composer,经常使用PHP的开发者对这个工具应该很熟悉,不熟悉的同学可以点击前面的链接进行脑补,文档是中文的,很好懂。这个小系统将会使用到三个类库:
phpmailer,predis,workerman。第一个是一个发送邮件的类库,可以点击这里查看他的相关信息,第二个类库是php对redis接口的封装,这里是他的源码地址,第三个是一个创建UDPserver的类库,这里是他的官方网站。
安装依赖的类库
首先新建一个项目目录,然后进入项目目录安装依赖
mkdir blog-observer
cd blog-observer
composer require phpmailer/phpmailer
composer require predis/predis
composer require workerman/workerman
执行完上面的命令之后,会在项目目录blog-observer目录下面看到下面几个文件composer.json,composer.lock和文件夹vender,composer.json中的内容如下,至此依赖的类库安装好了。
{
"require": {
"phpmailer/phpmailer": "^5.2",
"predis/predis": "^1.0",
"workerman/workerman": "^3.3"
}
}
监控博客更新&推送更新消息给UDP
下面是主要代码,由于是服务端程序,所以这里设置为daemon进程,我这里UDPserver为udp://127.0.0.1:1234
daemonize();
while(1)
{
//获取最新的几篇文章,看看是否需要推送
$c = file_get_contents(XML_URL);
$parse = @simplexml_load_string($c);
if($parse)
{
$count = count($parse->entry);
$count = $count > RECENT_NUM ? RECENT_NUM : $count;
$maynew = [];
for($i = 0; $i < $count; $i++)
{
$maynew[$parse->entry[$i]->link->attributes()->href->__toString()] = $parse->entry[$i]->title->__toString();
}
$body = "";
//是否推送
foreach($maynew as $url => $title)
{
if($client->sadd(SENDED_SET_KEY, $url))
{
//send EMAIL
$body .= "<a href='".$url."'>".$title."</a><br>";
}
}
if($body)
{
$msg = [];
$msg['type'] = 1;
$msg['mailbody'] = $body;
$start = 0;
while($mailaddrs = $client->lrange(EMAIL_LIST_KEY ,$start, ($start + EVERY_SEND_NUM -1 )))
{
$msg['mailaddrs'] = $mailaddrs;
$send_msg = json_encode($msg);
socket_sendto($sock, $send_msg, strlen($send_msg), 0, '127.0.0.1', 1234);
$start += EVERY_SEND_NUM;
}
}
}
sleep(GAP_SECONDS);
}
UDPserver程序
有了workerman,可以很方便的实现UDPserver,比自己写来的快得多。
$udp_worker = new Workerman\Worker("udp://0.0.0.0:".MAIL_UDP_PORT);
$udp_worker->count = 2;
$udp_worker->onMessage = function($connection, $data) use ($mail)
{
$arr = json_decode($data, true);
switch($arr['type'])
{
//发送邮件
case '1':
{
$mailaddrs = $arr['mailaddrs'];
if(!empty($mailaddrs) && $arr['mailbody'])
{
foreach($mailaddrs as $to)
{
$mail->clearAddresses();
$mail->AddAddress($to);
$mail->Body = $arr['mailbody'];
if(!$mail->Send())
{
echo "发送邮件失败:\n"."address:".$to."\n";
}
}
}
break;
}
default:
break;
}
};
Workerman\Worker::runAll();
启动监控程序
好了,至此所有的设计编码工作就完成了,现在启动程序,进程启动之后会议daemon的形式运行,不会随着终端的关闭而停止。
php xmldup.php start
php xmlmail.php
总结
这是一个小系统,当然了还有很多不规范的地方,比如daemon进程一般都会以字母d结尾,还有就是启动很不方便,要启动两次脚本,哈哈,当然了,这只是自己先来无事玩玩了,要真设计一个完成的系统估计会考虑很多很多的东西,加油吧,继续前进。
这里是github地址:blog-observer,自己试用的时候记得修改邮箱名称和密码。
如果谁也想第一时间获取到最新的阮老师的文章可以给我发邮件,我把你们的邮件地添加到邮件list中,但不保证会发送到,有时候关了电脑程序就停止了~
监控阮一峰老师的blog的更多相关文章
- react 入门教程 阮一峰老师真的是榜样
- 转自阮一峰老师博客 React 入门实例教程 作者: 阮一峰 日期: 2015年3月31日 现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Nati ...
- 读阮一峰老师 es6 入门笔记 —— 第一章
鉴于最近用 vuejs 框架开发项目,其中有很多涉及到 es6 语法不太理解所以便认真地读了一下这本书. 地址:http://es6.ruanyifeng.com/#README 第一章:let ,c ...
- 【js 笔记】读阮一峰老师 es6 入门笔记 —— 第一章
鉴于最近用 vuejs 框架开发项目,其中有很多涉及到 es6 语法不太理解所以便认真地读了一下这本书. 地址:http://es6.ruanyifeng.com/#README 第一章:let ...
- ES6特性:(阮一峰老师)学习总结
ES6(阮一峰)学习总结 1.块级作用域的引入 在ES6之前,js只有全局作用域和函数作用域,ES6中let关键字为其引入了块级作用域. { var a = 5; let b = 6; } con ...
- 关于阮一峰老师es6(第三版)中管道机制代码的理解浅析
最近正在学习阮一峰老师的es6(第三版)教材,在学到第七章<函数的扩展>中的箭头函数嵌套时,文中提到了一个关于“管道机制”的示例,文中源代码如下: //es6(第三版)教材中的管道机制源代 ...
- scss初学小结(转阮一峰老师SASS用法指南http://www.ruanyifeng.com/blog/2012/06/sass.html)
1.安装 SASS是Ruby语言写的,但是两者的语法没有关系.不懂Ruby,照样使用.只是必须先安装Ruby,然后再安装SASS. 假定你已经安装好了Ruby,接着在命令行输入下面的命令: gem i ...
- js-this的用法,来自阮一峰老师的文章
1. 随着函数使用场合的不同,this的值会发生变化.但是有一个总的原则,那就是this指的是,调用函数的那个对象. 或者说,this指向当前执行的函数的所有者. 2.情况一:纯粹的函数调用 这是函数 ...
- 【js 笔记】读阮一峰老师 es6 入门笔记 —— 第二章
第二章:变量的解构赋值 在es6 版本前,如果要为多个变量赋不同值,我想是件比较麻烦的事情.但es6 版本新推出了一个新技术那就是今天的主角变量的解构赋值. 变量解构赋值分为两种方法:数组解构赋值 和 ...
- flex布局 (引用阮一峰老师的flex布局-语法篇)
一.Flex 布局是什么? Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. 任何一个容器都可以指定为 Flex 布局. .box ...
随机推荐
- [SSIS] 在脚本里面使用数据库连接字符串进行查询等处理, 入坑
入坑.!!!!! SSIS 中dts包 设置的 ADO.Net连接, 在传入脚本的时候, 我要使用 数据库连接,进行数据的删除操作. 于是我使用了 了如下的 代码 使用的是windows 身份验证, ...
- 作业配置规范文档[MS SQL]
作业配置规范文档(MS SQL) 文档类型 MS SQL数据库作业配置规范文档 创建日期 2015-07-30 版本变化 V3.0 修改记录 修改人 修改日期 版本 修改描述 潇湘隐者 2015-08 ...
- MySQL Nested-Loop Join算法学习
不知不觉的玩了两年多的MySQL,发现很多人都说MySQL对比Oracle来说,优化器做的比较差,其实某种程度上来说确实是这样,但是毕竟MySQL才到5.7版本,Oracle都已经发展到12c了,今天 ...
- CocoaPods报错:The dependency `AFNetworking ` is not used in any concrete target
最近更新了下cocoapods,今天再pod update 就遇到这个错误: 大体意思就是说,库没有用到指定的target. 找了下资料,发现是新版CocoaPods在 Podfile里使用时,必须 ...
- redis 集群创建常见几个问题
Redis配置集群遇到问题及解决方法 配置完所有主节点后,报" ERR Invalid node address specified" 由于Redis-trib.rb 对域名或 ...
- C/S打包 客户端/windows程序 InstallShield
开发完成后,我们可以直接在Debug目录下启动exe,运行程序. 但是,要如何安装,添加到开始菜单.桌面快捷方式.任务栏等.如Office安装效果: 开始菜单: 快捷菜单: 打包步骤: 1.下载Ins ...
- WPF 无边框透明按钮
在实际开发过程中,有时候要设置一个无边框的按钮,或者无边框的透明按钮. 按钮效果如下: 1.当你应用telerik组件中的Button时,这个直接就可以设置 telerik:StyleManager. ...
- Postgresql 取随机数
取0和1之间的随机数 SELECT RANDOM(); 取介于两数之间的随机数 SELECT random()*(b-a)+a; ); 取介于两数之间的随机整数 SELECT floor(random ...
- 安卓直播开源: RTMP 推流SDK
前些日子在github上提交了基于GPUImage的IOS直播推流SDK(https://github.com/runner365/GPUImageRtmpPush) 最近整理了android直播推流 ...
- Url和Uri的区别
URL: URL是Uniform Resoure Locator(统一资源定位器)的缩写.就是WWW页的地址. 其URL地址格式排列为:scheme://host:Port/path其中 ·Inter ...