自昨天起,在一堆群裡,各路朋友土豪開始熱身發紅包,由於家裡網速是 50M 帶寬,外加 iPad,所以只要第一時間看見的,動手快,還是基本上能搞定。但這基本上是體力活,偶爾圖個樂還可以,如果長時間投在上面,又累又浪費時間,另外還有可能錯過,人肉的活,實在是不符合一個全棧工程師應該長時間幹的事情,全棧工程師要學會利用工具來幹這種枯燥無味的事。
第一時間想到的是自動化測試的工具,模擬手工去點擊,但是這種方式,一是開發難度較大,在這一天半天之內,並不一定能搞定,再長就不值得,浪費太多時間,並且其實是屬於外掛行為。
於是乎想到,我們需要的,其實是一個監控而已。只要有紅包了,能及時通知到,人去取就可以了。這樣既不需要費力地盯,同時還能一心二用,沒有紅包的時候,該幹嘛就可以了。這個監控也可以不是裝在手機或者iPad上的,也不形成外掛行為。
想好了,立馬乾,第一時間,當然是抓包。看看紅包來時,有沒有什麼特殊的包可以監聽的。
於是乎,在電腦上 啟動 Charles,這樣就起來了一個代理服務,默認的監聽埠是 8888.
再通過 /sbin/ifconfig 查到本機 IP, 192.168.199.246
這樣就得到了,代理伺服器的 IP 和埠。
然後將手機的上網連接加上代理 ,指向這個代理伺服器。如果不知道如何設置Android 代理 ,請自行百度搜索:「Android 設置代理」腦補。
通過監聽手機流量發現,在紅包到來時,Android 手機並沒有數據來回,
果真,在數個繁雜的請求中,發現了幾個現象 :
一是 Android 並沒有明顯文本數據包通過,感覺可能是Android 手機和伺服器是Socket 建立的直接連接。
二是 iOS 系統雖然有數據包經包,每收到消息都有,但是是二進位的,拆解起來,在短時間比較困難。
難道是沒有解了嗎?
功夫不負苦心人,每來一個紅包,客戶端向伺服器端取了一個圖片文件。應該是紅包的封面圖標。
OK,這就可以監聽了。
如下圖:
這個怎麼監聽呢?
一種辦法是像在 Windows 中,可以取得程序的 Handle ,然後讀取程序右邊這個列表的數據,不過這也不是很快能搞出來的。稍微查了一下,發現蘋果上,還不是特別好加這個功能(未嚴格確認)。
想到最好的辦法是不用 Charles 做代理,找個開源的代理。找開源的代理,勿庸置疑,必須是 Nginx 了。
Nginx 簡單,找了一份 nginx-1.6.2 的源碼,下下來。 直接 configure & make。就編譯出來了。
編寫了如下配置,存在代碼的 objs 目錄下:
練練手
1
2
3
4
5
6
7
8
9
10
11
12
13
worker_processes 1;
events {
worker_connections 1024;
}
http{
server {
listen 9999;
location / {
proxy_pass http://$http_host$request_uri;
}
}
}
進入代碼的 objs 目錄,使用 ./nginx -c nginx.conf 起來。
把手機代理指向 192.168.199.246:9999
果真,在紅包到來時,在Nginx 日誌裡發現了日誌。
練練手
1
2
3
4
5
bash-3.2# cat /usr/local/nginx/logs/access.log |grep hongbao|tail -10
192.168.199.211 - - [18/Feb/2015:08:35:00 +0800] "GET http://hongbao.weixin.qq.com/pay/DefaultCover.png HTTP/1.1" 502 172 "-" "Dalvik/1.6.0 (Linux; U; Android 4.1.2; HUAWEI C8813Q Build/HuaweiC8813Q)"
192.168.199.211 - - [18/Feb/2015:08:37:44 +0800] "GET http://hongbao.weixin.qq.com/pay/DefaultCover.png HTTP/1.1" 502 172 "-" "Dalvik/1.6.0 (Linux; U; Android 4.1.2; HUAWEI C8813Q Build/HuaweiC8813Q)"
192.168.199.211 - - [18/Feb/2015:08:39:07 +0800] "GET http://wx.gtimg.com/hongbao/img/hongbao.png HTTP/1.1" 502 172 "-" "Dalvik/1.6.0 (Linux; U; Android 4.1.2; HUAWEI C8813Q Build/HuaweiC8813Q)"
192.168.199.211 - - [18/Feb/2015:08:44:54 +0800] "GET http://wx.gtimg.com/hongbao/img/hongbao.png HTTP/1.1" 502 172 "-" "Dalvik/1.6.0 (Linux; U; Android 4.1.2; HUAWEI C8813Q Build/HuaweiC8813Q)"
這就好辦了,監控這個日誌就可以了嘛。第一個想到的是監聽日誌。寫了如下代碼:
練練手
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$lastline = "";
while(1)
{
$line = `tail -1 /usr/local/nginx/logs/access.log`;
if(($lastline != $line) && strpos($line, "hongbao")!==false)
{
$cmd = "say -v Bells \"dong\"";
system($cmd);
$cmd = "osascript -e 'tell app \"System Events\" to display dialog \"有紅包了!\"'";
echo $cmd."\n";
}
echo date("Y-m-d H:i:s")."\n";
usleep(500000);
$lastline = $line;
}
這段代碼,實現了對日誌的監聽,並且在有紅包的時候,能夠發聲報警。開始還設計了一個彈出對話框的功能,但是發現影響幹別的事情,所以先注釋了。並且加了判斷,只報一次警。本來開始設計成報多次,發現紅包來得集中時,就無法判斷了。一次就夠了。開始本來也是停留1秒,發現1秒也有點長,變成了停留0.5秒。
到這就算完了嗎?還沒有完,這個是去檢測日誌了。日誌從接收請求,寫入日誌, 再由監控程序讀到,是不是還有更快的呢?
答案是肯定的,直接在 Nginx 相關的模塊,比如 ngx_http_log_module 模塊中,有 ngx_http_request_t 的地方加入如下代碼,重新編譯 nginx
練練手
1
2
3
4
if(strstr(r->uri.data, "hongbao")!=NULL)
{
system("/usr/bin/say -v Bells \"dong\"");
}
這樣經過測試,發現不行。 後來想,是不是 變成daemon 的原因?
果真,在nginx.conf 中加入一行:
練練手
當紅包來時,nginx 就能報警了,這個時候,日誌監控也可以去掉了。
現在紅包就等通知就好了。空出來的時候,可以和小朋友玩,看書、寫代碼、聽音樂啦!
大家可以看看我的戰果,僅以此文獻給 全棧工程師朋友們。
現在基本上能用了,如果是5秒以內搶光的,比較困難,10秒以內的。反應過來還是來得及的呵。
全棧工程師,就是這麼任性,要想知道,如何成為全棧工程師,歡迎點擊閱讀原文。