App中如何實現訊息推送
轉載地址:https://zhuanlan.zhihu.com/p/19801751
如今的手機每天都會被各種App的訊息推送覆蓋,訊息推送也成了週末去哪兒APP增加自己曝光量的一種重要手段。訊息推送的技術也日漸成熟,各種平臺紛紛出現,搶佔這一業務,本文就從技術角度來吐槽吐槽。本文是由我們的無線開發團隊原創和整理,如果轉載請務必先諮詢本團隊。
首先介紹下訊息推送,即Push的技術基礎:
什麼叫Push?
真正的Push應該是隻要一個Client裝置連線到網際網路中,什麼也不做等在那裡,Server端隨時都可以將資料(訊息是資料的一種)傳送到這個Client上,就好像Server等在那裡,Client隨時可以訪問Server一樣。
用Server端做個類比,當一個Web Server在網際網路上部署好以後,任何一臺電腦都可以通過網際網路去訪問Server:從Server獲取資料、向Server提交資料。向Server提交資料實際就是Client Push資料到Server。在這個模式中,Server所做的事情就是等待,等待任意的Client主動來訪問它,並且不需要和Client端保持連線。Server是如何做到這點的呢,實際上是通過listen的方式,具體來說是socket的listen,Server端不需要做額外的事情,只要告訴socket,你去listen吧,有Client請求過來就交給對應的程式去完成吧,就這麼簡單。
Client端的Push是否能做到這點呢,我們這裡只考慮Client的裝置是智慧機的情況,主要就是Android、iOS,還有winPhone?大概吧。Android和iOS都是基於linux系統的,有完整的網路協議架構,所以使用socket完全沒有問題,winPhone作為一個智慧機來說,我想也是沒有問題的。所以對於這些智慧機來說,讓一個socket去listen,等待網際網路上的任意一臺其他裝置來訪問是可行的,Server Push資料給Client只需要去連線Client的socket就可以了。
事情是這麼簡單嗎?顯然不是,不然就不會有各個大小公司跳出來做平臺了。
ps:首先我們要了解socket是什麼,socket是基於tcp/ip協議的一個實現,而tcp/ip是整個網際網路的協議基礎。關於tcp/ip,socket具體內容不在這裡贅述,不瞭解的可以去查相關資料。
Server端和Client端有一個很重要的區別,Server端是有固定的公網ip的,而Client端的ip不是固定的,甚至不一定具有公網ip。Client訪問Server時,實際是通過ip找到Server進行訪問的(域名?域名最終也是被解析成ip),有固定的公網ip才方便網際網路上的其他裝置來訪問。而反過來Server想找某個Client時,由於Client的ip不固定,Server端是無法找到Client的。所以即使Client這裡放了一個socket在listen,Server找不到Client,還是連線不上Client。
所以Client是無法使用Server的這種模式去被動接受Push的。是否有辦法讓Server端知道Client的ip呢,比如每次Client更換ip以後將ip發給Server?這種方法顯然是成本高且不可靠的。
所以,目前的Push技術實現基本都是Client主動連線Server,鑽牛角尖來講,現在的Push其實都是偽Push。下面簡單講兩種方式:
一、輪詢法:
這種方法最簡單,Client每過一段時間向Server請求一次資料。優缺點很明顯,優點是實現簡單;缺點是間隔時間不好控制,並且消耗大(電量、流量)。
二、長連線法:
還是從socket入手(又是這貨?),Client使用socket連線Server,並且保持socket連線,Server隨時可以通過這個socket傳送資料給Client。優點:最有效,客戶端裝置消耗比第一種小(裝置應該從系統層對socket的長連線做優化,socket連結維護成本從客戶端來講應該是小於頻繁的http請求的);缺點:服務端壓力大,每一個裝置都需要一個socket連線。
還有一些其他協議比如xmpp,其實也逃不過上面兩種方式,只是做了一些封裝。或者還有一種非網際網路方式的做法,比如監聽簡訊法,要push的時候,先發一條手機到目的手機,Client監聽到了標的簡訊,然後向Server請求資料,不過像這類劍走偏鋒的方法,限制條件也很多,不是很實用。
總結一下,目前各個推送平臺的實現都是基於長連線法的,如果App要自己實現推送,也是建議使用這種方式。但是如果每個App都用一個長連線,那麼手機也吃不消了,所以又有一些其他技術來實現,我們下篇再講。