监控阮1峰老师的blog
监控阮一峰老师的blog
引言
阮一峰大家基本都认识,很厉害的一个人,经济学博士,文章写得很棒,知识面很广泛,计算机、算法、英语、文采,这是能想到的他的一些标签,他的博客应该算是最受欢迎的博客之一了。
我经常回去看他的博客,但有时候时间长了,再次去看,发现他已经有好几篇新文章了,我就在想,能不能自己写个程序,监控的他博客,当他有新文章的时候,第一时间推送给我。
思路
他的博客中有一个feed,是一个返回xml格式文档的接口,这个接口是最新的文章列表,总共15篇,可以通过监控这个接口中前几篇文章列表的变化来间接的检测他的文章更新,如果有新的文章马上给我的邮箱发送邮件,这样我就可以尽可能早的get到阮老师的最新文章了。
这是设计思路图:
首先就是rss解析了,这个使用php的原生函数simplexml_load_string得到一个解析之后的SimpleXMLElement对象,通过该对象可以很轻松的获取到阮老师更新的前几篇文章。然后和redis中的已发送文章列表集合作对比,如果有新的更新,将更新的信息发送给UDPserver,让UDPserver去发送邮件给用户列表。检测程序循环执行,每10分钟跑一次。
开始编码
有了思路编码就很快了(这里其实优化了好几次,刚开始的时候思路也没有这么明了,边做边改,当然了,还是要慢慢锻炼,开始之前尽可能多的完善思路)。
使用PHP依赖管理利器——Composer,经常使用PHP的开发者对这个工具应该很熟悉,不熟悉的同学可以点击前面的链接进行脑补,文档是中文的,很好懂。这个小系统将会使用到三个类库:phpmailer
,predis
,workerman
。第一个是一个发送邮件的类库,可以点击这里查看他的相关信息,第二个类库是php对redis接口的封装,这里是他的源码地址,第三个是一个创建UDPserver的类库,这里是他的官方网站。
安装依赖的类库
首先新建一个项目目录,然后进入项目目录安装依赖
<code>mkdir blog-observercd blog-observercomposer require phpmailer/phpmailercomposer require predis/prediscomposer require workerman/workerman</code>
执行完上面的命令之后,会在项目目录blog-observer目录下面看到下面几个文件composer.json
,composer.lock
和文件夹vender
,composer.json中的内容如下,至此依赖的类库安装好了。
<code class="sourceCode json"><span class="fu">{</span> <span class="dt">"require"</span><span class="fu">:</span> <span class="fu">{</span> <span class="dt">"phpmailer/phpmailer"</span><span class="fu">:</span> <span class="st">"^5.2"</span><span class="fu">,</span> <span class="dt">"predis/predis"</span><span class="fu">:</span> <span class="st">"^1.0"</span><span class="fu">,</span> <span class="dt">"workerman/workerman"</span><span class="fu">:</span> <span class="st">"^3.3"</span> <span class="fu">}</span><span class="fu">}</span></code>
监控博客更新&推送更新消息给UDP
下面是主要代码,由于是服务端程序,所以这里设置为daemon进程,我这里UDPserver为udp://127.0.0.1:1234
<code class="sourceCode php">daemonize<span class="ot">();</span><span class="kw">while</span><span class="ot">(</span><span class="dv">1</span><span class="ot">)</span>{ <span class="co">//获取最新的几篇文章,看看是否需要推送</span> <span class="kw">$c</span> = <span class="fu">file_get_contents</span><span class="ot">(</span><span class="kw">XML_URL</span><span class="ot">);</span> <span class="kw">$parse</span> = <span class="er">@</span><span class="fu">simplexml_load_string</span><span class="ot">(</span><span class="kw">$c</span><span class="ot">);</span> <span class="kw">if</span><span class="ot">(</span><span class="kw">$parse</span><span class="ot">)</span> { <span class="kw">$count</span> = <span class="fu">count</span><span class="ot">(</span><span class="kw">$parse</span>->entry<span class="ot">);</span> <span class="kw">$count</span> = <span class="kw">$count</span> > <span class="kw">RECENT_NUM</span> <span class="ot">?</span> <span class="kw">RECENT_NUM</span> <span class="ot">:</span> <span class="kw">$count</span><span class="ot">;</span> <span class="kw">$maynew</span> = <span class="ot">[];</span> <span class="kw">for</span><span class="ot">(</span><span class="kw">$i</span> = <span class="dv">0</span><span class="ot">;</span> <span class="kw">$i</span> < <span class="kw">$count</span><span class="ot">;</span> <span class="kw">$i</span>++<span class="ot">)</span> { <span class="kw">$maynew</span><span class="ot">[</span><span class="kw">$parse</span>->entry<span class="ot">[</span><span class="kw">$i</span><span class="ot">]</span>-><span class="fu">link</span>->attributes<span class="ot">()</span>->href-><span class="fu">__toString</span><span class="ot">()]</span> = <span class="kw">$parse</span>->entry<span class="ot">[</span><span class="kw">$i</span><span class="ot">]</span>->title-><span class="fu">__toString</span><span class="ot">();</span> } <span class="kw">$body</span> = <span class="st">""</span><span class="ot">;</span> <span class="co">//是否推送</span> <span class="kw">foreach</span><span class="ot">(</span><span class="kw">$maynew</span> <span class="kw">as</span> <span class="kw">$url</span> => <span class="kw">$title</span><span class="ot">)</span> { <span class="kw">if</span><span class="ot">(</span><span class="kw">$client</span>->sadd<span class="ot">(</span><span class="kw">SENDED_SET_KEY</span><span class="ot">,</span> <span class="kw">$url</span><span class="ot">))</span> { <span class="co">//send EMAIL</span> <span class="kw">$body</span> .= <span class="st">"<a href='"</span>.<span class="kw">$url</span>.<span class="st">"'>"</span>.<span class="kw">$title</span>.<span class="st">"</a><br>"</span><span class="ot">;</span> } } <span class="kw">if</span><span class="ot">(</span><span class="kw">$body</span><span class="ot">)</span> { <span class="kw">$msg</span> = <span class="ot">[];</span> <span class="kw">$msg</span><span class="ot">[</span><span class="st">'type'</span><span class="ot">]</span> = <span class="dv">1</span><span class="ot">;</span> <span class="kw">$msg</span><span class="ot">[</span><span class="st">'mailbody'</span><span class="ot">]</span> = <span class="kw">$body</span><span class="ot">;</span> <span class="kw">$start</span> = <span class="dv">0</span><span class="ot">;</span> <span class="kw">while</span><span class="ot">(</span><span class="kw">$mailaddrs</span> = <span class="kw">$client</span>->lrange<span class="ot">(</span><span class="kw">EMAIL_LIST_KEY</span> <span class="ot">,</span><span class="kw">$start</span><span class="ot">,</span> <span class="ot">(</span><span class="kw">$start</span> + <span class="kw">EVERY_SEND_NUM</span> -<span class="dv">1</span> <span class="ot">)))</span> { <span class="kw">$msg</span><span class="ot">[</span><span class="st">'mailaddrs'</span><span class="ot">]</span> = <span class="kw">$mailaddrs</span><span class="ot">;</span> <span class="kw">$send_msg</span> = <span class="fu">json_encode</span><span class="ot">(</span><span class="kw">$msg</span><span class="ot">);</span> <span class="fu">socket_sendto</span><span class="ot">(</span><span class="kw">$sock</span><span class="ot">,</span> <span class="kw">$send_msg</span><span class="ot">,</span> <span class="fu">strlen</span><span class="ot">(</span><span class="kw">$send_msg</span><span class="ot">),</span> <span class="dv">0</span><span class="ot">,</span> <span class="st">'127.0.0.1'</span><span class="ot">,</span> <span class="dv">1234</span><span class="ot">);</span> <span class="kw">$start</span> += <span class="kw">EVERY_SEND_NUM</span><span class="ot">;</span> } } } <span class="fu">sleep</span><span class="ot">(</span><span class="kw">GAP_SECONDS</span><span class="ot">);</span>}</code>
UDPserver程序
有了workerman,可以很方便的实现UDPserver,比自己写来的快得多。
<code class="sourceCode php"><span class="kw">$udp_worker</span> = <span class="kw">new</span> Workerman\Worker<span class="ot">(</span><span class="st">"udp://0.0.0.0:"</span>.<span class="kw">MAIL_UDP_PORT</span><span class="ot">);</span><span class="kw">$udp_worker</span>-><span class="fu">count</span> = <span class="dv">2</span><span class="ot">;</span><span class="kw">$udp_worker</span>->onMessage = <span class="kw">function</span><span class="ot">(</span><span class="kw">$connection</span><span class="ot">,</span> <span class="kw">$data</span><span class="ot">)</span> <span class="kw">use</span> <span class="ot">(</span><span class="kw">$mail</span><span class="ot">)</span>{ <span class="kw">$arr</span> = <span class="fu">json_decode</span><span class="ot">(</span><span class="kw">$data</span><span class="ot">,</span> <span class="kw">true</span><span class="ot">);</span> <span class="kw">switch</span><span class="ot">(</span><span class="kw">$arr</span><span class="ot">[</span><span class="st">'type'</span><span class="ot">])</span> { <span class="co">//发送邮件</span> <span class="kw">case </span><span class="st">'1'</span><span class="ot">:</span> { <span class="kw">$mailaddrs</span> = <span class="kw">$arr</span><span class="ot">[</span><span class="st">'mailaddrs'</span><span class="ot">];</span> <span class="kw">if</span><span class="ot">(</span>!<span class="fu">empty</span><span class="ot">(</span><span class="kw">$mailaddrs</span><span class="ot">)</span> && <span class="kw">$arr</span><span class="ot">[</span><span class="st">'mailbody'</span><span class="ot">])</span> { <span class="kw">foreach</span><span class="ot">(</span><span class="kw">$mailaddrs</span> <span class="kw">as</span> <span class="kw">$to</span><span class="ot">)</span> { <span class="kw">$mail</span>->clearAddresses<span class="ot">();</span> <span class="kw">$mail</span>->AddAddress<span class="ot">(</span><span class="kw">$to</span><span class="ot">);</span> <span class="kw">$mail</span>->Body = <span class="kw">$arr</span><span class="ot">[</span><span class="st">'mailbody'</span><span class="ot">];</span> <span class="kw">if</span><span class="ot">(</span>!<span class="kw">$mail</span>->Send<span class="ot">())</span> { <span class="fu">echo</span> <span class="st">"发送邮件失败:</span><span class="kw">\n</span><span class="st">"</span>.<span class="st">"address:"</span>.<span class="kw">$to</span>.<span class="st">"</span><span class="kw">\n</span><span class="st">"</span><span class="ot">;</span> } } } <span class="kw">break</span><span class="ot">;</span> } <span class="kw">default:</span> <span class="kw">break</span><span class="ot">;</span> }}<span class="ot">;</span>Workerman\Worker::runAll<span class="ot">();</span></code>
启动监控程序
好了,至此所有的设计编码工作就完成了,现在启动程序,进程启动之后会议daemon的形式运行,不会随着终端的关闭而停止。
<code>php xmldup.php startphp xmlmail.php</code>
总结
这是一个小系统,当然了还有很多不规范的地方,比如daemon进程一般都会以字母d
结尾,还有就是启动很不方便,要启动两次脚本,哈哈,当然了,这只是自己先来无事玩玩了,要真设计一个完成的系统估计会考虑很多很多的东西,加油吧,继续前进。
这里是github地址:blog-observer,自己试用的时候记得修改邮箱名称和密码。
如果谁也想第一时间获取到最新的阮老师的文章可以给我发邮件,我把你们的邮件地添加到邮件list中,但不保证会发送到,有时候关了电脑程序就停止了~
- 7楼飞凡123
- 时间间隔设定的是多少
- Re: 奔跑的Man
- @飞凡123,测试的时候是600s,这个时间不能太短,太短了没多大意义,还浪费阮老师的服务器资源
- 6楼Liez
- 马克
- 5楼白丸
- 真是好学生
- 4楼旭宝爱吃鱼
- 可以,赞
- Re: 奔跑的Man
- @旭宝爱吃鱼,THX
- 3楼wzx_xle
- 我用的foxmail的rss订阅功能
- Re: 奔跑的Man
- @wzx_xle,@星夜落尘,RSS订阅?行,你们可以啊,我又没说不可以,你要用RSS订阅我啥也不说了,我就喜欢DIV,得劲了吧~~
- 2楼永远的麦子
- 写得很好,也很喜欢阮老师的博客,上次了解到阮老师的博客是学习git的时候了解到阮老师的。
- Re: 奔跑的Man
- @永远的麦子,谢谢了。多像阮老师学习,哈哈,多涉猎技术之外的知识充实自己
- 1楼星夜落尘
- 不是有rss订阅吗。。。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

许多用户在选择智能手表的时候都会选择的华为的品牌,其中华为GT3pro和GT4都是非常热门的选择,不少用户都很好奇华为GT3pro和GT4有什么区别,下面就就给大家介绍一下二者。华为GT3pro和GT4有什么区别一、外观GT4:46mm和41mm,材质是玻璃表镜+不锈钢机身+高分纤维后壳。GT3pro:46.6mm和42.9mm,材质是蓝宝石玻璃表镜+钛金属机身/陶瓷机身+陶瓷后壳二、健康GT4:采用最新的华为Truseen5.5+算法,结果会更加的精准。GT3pro:多了ECG心电图和血管及安

实现Workerman文档中的文件上传与下载,需要具体代码示例引言:Workerman是一款高性能的PHP异步网络通讯框架,具备简洁、高效、易用等特点。在实际开发中,文件上传和下载是常见的功能需求,本文将介绍如何使用Workerman框架实现文件的上传和下载,并给出具体的代码示例。一、文件上传:文件上传是指将本地计算机上的文件传输至服务器端的操作。下面是使用

如何实现Workerman文档的基本使用方法简介:Workerman是一个高性能的PHP开发框架,它可以帮助开发者轻松构建高并发的网络应用程序。本文将介绍Workerman的基本使用方法,包括安装和配置、创建服务和监听端口、处理客户端请求等。并给出相应的代码示例。一、安装和配置Workerman在命令行中输入以下命令来安装Workerman:c

Swoole 和 Workerman 都是高性能 PHP 服务器框架。Swoole 以其异步处理、出色的性能和可扩展性而闻名,适用于需要处理大量并发请求和高吞吐量的项目。Workerman 提供了异步和同步模式的灵活性,具有直观的 API,更适合易用性和处理较低并发量的项目。

Workerman开发:基于UDP协议的实时视频通话摘要:本文将介绍如何使用Workerman框架实现基于UDP协议的实时视频通话功能。我们将深入了解UDP协议的特点,并通过代码示例展示如何搭建一个简单但完整的实时视频通话应用。引言:在网络通信中,实时视频通话是一项非常重要的功能。传统的TCP协议在实现实时性较高的视频通话时,可能会有传输延迟等问题。而UDP

如何使用Workerman搭建高可用性负载均衡系统,需要具体代码示例在现代技术领域中,随着互联网的快速发展,越来越多的网站和应用程序需要处理大量的并发请求。为了实现高可用性和高性能,负载均衡系统成为了必不可少的组件之一。本文将介绍如何使用PHP开源框架Workerman搭建一个高可用性的负载均衡系统,并提供具体的代码示例。一、Workerman简介Worke

如何实现Workerman文档中的反向代理功能,需要具体代码示例简介:Workerman是一款高性能的PHP多进程网络通信框架,提供了丰富的功能和强大的性能,广泛应用于Web实时通讯、长连接服务等场景。其中,Workerman还支持反向代理功能,可以实现服务器对外提供服务时的负载均衡和静态资源缓存等功能。本篇文章将介绍如何使用Workerman实现反向代理功

如何实现Workerman文档中的定时器功能Workerman是一款强大的PHP异步网络通信框架,它提供了丰富的功能,其中就包括定时器功能。使用定时器可以在指定的时间间隔内执行代码,非常适合定时任务、轮询等应用场景。接下来,我将详细介绍如何在Workerman中实现定时器功能,并提供具体的代码示例。第一步:安装Workerman首先,我们需要安装Worker
