阮一峯你們基本都認識,很厲害的一我的,經濟學博士,文章寫得很棒,知識面很普遍,計算機、算法、英語、文采,這是能想到的他的一些標籤,他的博客應該算是最受歡迎的博客之一了。
我常常回去看他的博客,但有時候時間長了,再次去看,發現他已經有好幾篇新文章了,我就在想,能不能本身寫個程序,監控的他博客,當他有新文章的時候,第一時間推送給我。php
他的博客中有一個feed,是一個返回xml格式文檔的接口,這個接口是最新的文章列表,總共15篇,能夠經過監控這個接口中前幾篇文章列表的變化來間接的檢測他的文章更新,若是有新的文章立刻給個人郵箱發送郵件,這樣我就能夠儘量早的get到阮老師的最新文章了。
這是設計思路圖:
git
首先就是rss解析了,這個使用php的原生函數simplexml_load_string獲得一個解析以後的SimpleXMLElement對象,經過該對象能夠很輕鬆的獲取到阮老師更新的前幾篇文章。而後和redis中的已發送文章列表集合做對比,若是有新的更新,將更新的信息發送給UDPserver,讓UDPserver去發送郵件給用戶列表。檢測程序循環執行,每10分鐘跑一次。github
有了思路編碼就很快了(這裏其實優化了好幾回,剛開始的時候思路也沒有這麼明瞭,邊作邊改,固然了,仍是要慢慢鍛鍊,開始以前儘量多的完善思路)。
使用PHP依賴管理利器——Composer,常用PHP的開發者對這個工具應該很熟悉,不熟悉的同窗能夠點擊前面的連接進行腦補,文檔是中文的,很好懂。這個小系統將會使用到三個類庫:
phpmailer
,predis
,workerman
。第一個是一個發送郵件的類庫,能夠點擊這裏查看他的相關信息,第二個類庫是php對redis接口的封裝,這裏是他的源碼地址,第三個是一個建立UDPserver的類庫,這裏是他的官方網站。redis
首先新建一個項目目錄,而後進入項目目錄安裝依賴算法
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中的內容以下,至此依賴的類庫安裝好了。shell
{ "require": { "phpmailer/phpmailer": "^5.2", "predis/predis": "^1.0", "workerman/workerman": "^3.3" } }
下面是主要代碼,因爲是服務端程序,因此這裏設置爲daemon進程,我這裏UDPserver爲udp://127.0.0.1:1234
json
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); }
有了workerman,能夠很方便的實現UDPserver,比本身寫來的快得多。composer
$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的形式運行,不會隨着終端的關閉而中止。socket
php xmldup.php start php xmlmail.php
這是一個小系統,固然了還有不少不規範的地方,好比daemon進程通常都會以字母d
結尾,還有就是啓動很不方便,要啓動兩次腳本,哈哈,固然了,這只是本身先來無事玩玩了,要真設計一個完成的系統估計會考慮不少不少的東西,加油吧,繼續前進。函數
這裏是github地址:blog-observer,本身試用的時候記得修改郵箱名稱和密碼。
若是誰也想第一時間獲取到最新的阮老師的文章能夠給我發郵件,我把大家的郵件地添加到郵件list中,但不保證會發送到,有時候關了電腦程序就中止了~