推送與IM即時聊天可行性分析報告與解決方案彙總

推送與IM即時聊天可行性分析報告與解決方案彙總

 

第一部分:理論分析

1、前言

       目前市面上有不少第三方推送與IM即時聊天解決方案,如騰訊信鴿、極光推送、網易雲信等第三方平臺,可是這些平臺有時並不能知足咱們的需求,好比要求咱們的系統必須部署到內網環境等狀況,或者出於公司知識產權等考慮,這時咱們就不得不本身想辦法搭建推送服務器。java

 

2、自建推送/IM服務器要考慮的問題

       隨着社交應用的普及,人們對即時聊天的要求也愈來愈高,截止2017年上半年爲止,我大概總結了一下,一個基本的聊天應用起碼要考慮到如下幾點纔算是一個可用的方案:android

  • QoS,對於傳送質量的要求:未成功發送的消息如何保證送達?重試時如何保證不重複送達?
  • 實時網絡監測:如何在鏈接已斷開時及時通知用戶?
  • 數據持久化:聊天記錄如何保存?
  • 消息隊列:一次發送多條消息時如何保證有序到達?
  • 發送回執與狀態顯示:只有在發送成功狀況下消息纔不顯示任何額外標識,不然在發送過程當中要顯示Loading圖標,發送失敗後要顯示感嘆號圖標,全部這些是否可經過監聽發送回執來作到?推送服務器是否支持發送回執?

 

3、推送實現的可選方式

(1)本身寫socket長鏈接:

       其實不少人建議咱們在手機端本身寫一個socket長鏈接,而後採用輪循的方式不斷從推送服務器去取數據,不能否認早些年在移動互聯網剛開始發展的階段這確實是一種解決方案,那時候沒有成熟的協議,沒有成熟的組件,也沒有解決以上第二點中提出的那麼多須要注意的點。並且隨着時代的發展,這種方式的缺點也愈來愈明顯,最要命的是它耗電、耗流量、耗系統資源,並且還不穩定,若是用戶量達到必定數量服務端是絕對受不了了幾萬臺終端同時用這種方式輪循的。git

(2)使用官方推送渠道:

       對於蘋果手機來講,推送的實現方式比較簡單,蘋果公司統一提供了全局惟一的socket長鏈接,全部應用共享這一鏈接,全部推送也都通過這個鏈接來推送,開發人員只須要接入蘋果的APNs便可。其實對Android手機來講,也有相似的實現方式,Google公司仿照蘋果公司的模式也爲Android操做系統提供了相似的「官方」推送服務器,叫作谷歌雲消息系統(Google Cloud Messaging,簡稱GCM),可是因爲要鏈接Google的服務器,衆所周知的緣由,這一服務沒法在國內使用,若是咱們想實現包括Android在內的全平臺的統一推送服務,就要另想辦法了。github

(3)根據已有的成熟的推送協議自已搭建標準的推送服務器:

       其實除了本身寫socket長鏈接和使用官方渠道以外,目前已經有不少成熟的推送協議可供選擇,比較流行的幾種即時通訊協議爲ddpush、xmpp和mqtt,有關這幾種推送協議的優缺點有一篇文章你們能夠參考一下:數據庫

《總結ddpush、xmpp、mqtt在作推送的時候的選擇》,連接:後端

http://blog.csdn.net/languobeibei/article/details/56288947緩存

 

4、選擇哪一種協議

(1)功勳元老xmpp協議:

       其實xmpp協議在手機早期發展階段用的仍是比較多的,在Android 2.X時代咱們就曾經使用過這種協議,在實現xmpp協議的服務器框架中,最著名的當屬Openfire,咱們只須要下載Openfire的安裝包並安裝部署到咱們的Linux主機,並作簡單的配置就可使用了,可是這種協議其實已經不在適合今天的互聯網世界,其xml格式的報文相對冗餘,且沒有對消息傳輸質量等方面作詳細的規定,如今已經不多使用。tomcat

(2)互聯網與物聯網行業的新星:mqtt協議

       因爲xmpp協議有各類不足,IBM公司推出的mqtt協議在近些年愈來愈受歡迎,這種協議使用二進制流進行傳輸,內容冗餘很是少,並且mqtt協議不只僅規定了報文格式,還對消息質量、消息持久化等方面作了詳細規定,並且支持服務器的橋接,對於多臺服務器聯合部署也比較方便,特別適合今天作爲IM即時聊天的解決方案,所以,咱們推薦使用mqtt協議來實現咱們的推送方案。安全

 

5、mqtt協議簡介

       其實不管是xmpp協議仍是mqtt協議,都是基於tcp協議封裝的應用層協議,在訪問時都是能過tcp://的格式來鏈接服務器。服務器

       Mqtt協議基於發佈/訂閱模式來構建,實現了消息發送端和接收端的解耦,咱們可使用這種模式來構建點對點的聊天,也能夠輕鬆構建一個羣聊,發送端發佈一個話題(topic),接收端訂閱(subscribe)這個topic便可,而且mqtt協議提供了消息質量的支持,當QoS的等級爲2時,發送端和接收端能夠經過屢次握手的方式實現消息有且僅一次送達,即便是接收端離線也能夠實現離線消息的正確接收,咱們能夠配置服務器將離線消息緩存到內存或者數據庫中,這些內容在mqtt協議中都作了明確規定。

       在傳輸安全方式,mqtt協議也明確規定了SSL/TLS的傳輸方式,若是有安全傳輸的需求也能夠知足。

       在數據持久化方面,mqtt協議明確規定了消息可存放於內存或數據庫中,而且開放給開發人員自由選擇。

 

第二部分:實戰

1、基於mqtt協議的Apollo服務器和mosquitto服務器的安裝與配置

       近年來關於mqtt的相關文檔也愈來愈豐富,針對mqtt的服務器組件也愈來愈多,比較著名的有Apache基金組織的ActiveMQ Apollo和eclipse公司推出的mosquitto,拿mosquitto來講,咱們只須要到http://mosquitto.org下載相應的安裝包,並安裝到咱們的Linux主機就能夠搭建一臺基於mqtt協議的推送服務器,關於如何安裝部署mosquitto服務器,網上有大量的文章可供參考,apollo服務器的下載安裝也有不少文章介紹,你們能夠自行百度,這裏能夠推薦兩篇文章:

Mosquitto的下載及安裝:

http://blog.csdn.net/xukai871105/article/details/39252653

Apollo的下載及安裝:

http://blog.csdn.net/qq_29196551/article/details/51488340

 

2、開發API的選擇

       其實通過前邊選擇協議並安裝服務器,咱們的推送服務已經算是搭建好了,至於如何訪問這個mqtt服務器是客戶端要作的事情了,只要咱們按照mqtt規定的方式鏈接推送服務器就能夠了,可是因爲mqtt協議規定的細節相對比較多,若是咱們硬編碼的話工做量仍是比較大的,好在已經有人爲咱們封裝過這些API了,這裏推薦使用eclipse公司的paho,官網地址是http://www.eclipse.org/paho/,paho提供了多種語言的實現,包括Java、Android、Python、JavaScript、.Net(C#)、C/C++等實現,若是使用PHP語言也能夠參考tokudu-PhpMQTTClient,若是考慮到兼容蘋果手機,能夠參考這篇文章:

《MQTT 協議(三):實戰篇》

http://www.jianshu.com/p/b093fe6c3f10?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=qq

       這篇文章介紹了用 Objective-C 封裝的 MQTT 框架:MQTT-Client-Framework的使用,這樣咱們就可使用一臺推送服務器兼容Android和IOS兩大平臺了,我猜蘋果的這套框架底層應該也是經過蘋果的APNs來鏈接的。

 

Paho的官網也給出了各類實現方式的樣例,好比Java的Demo在Github中的網址爲:

https://github.com/eclipse/paho.mqtt.java

Android的代碼樣例爲:

https://github.com/eclipse/paho.mqtt.android

在Android的樣例中,eclipse公司還給出了一個現成的mqtt服務器地址

tcp://iot.eclipse.org:1883

若是想先看看效果,暫時沒空搭建mqtt服務器的話,可使用這個服務器來作一些演示。

 

3、容易混淆的概念:服務器、客戶端

       以前查詢了不少有關搭建推送服務器的資料,發現不少朋友都忽略了幾個最最基本的概念,什麼叫服務器?什麼叫客戶端?因此我認爲有必要在文章的最後對這個概念進行一些說明。

       其實在傳統的手機APP開發當中,咱們通常把手機稱做客戶端,把給手機提供http接口的後端稱做服務器,服務器能夠由基於SpringMVC的Java來構建,也能夠由PHP、Python等語言構建。

       可是在推送服務器的領域,我認爲有必要澄清一下「服務器」的概念,在這個領域裏,只有一個東西能夠被稱爲服務器,就是負責推送的那臺「推送服務器」,除此以外其它全部的設備在它看來都是客戶端,理論上講,咱們只須要搭建一個mosquitto或Apollo服務器,再用幾臺手機經過mqtt協議鏈接到這臺服務器就能夠實現即時聊天了,而咱們所謂的Java服務器後臺、PHP服務器後臺則徹底能夠不要。

       而若是咱們須要經過咱們本身的服務器管理後臺給手機用戶推送消息時,咱們就能夠在咱們Java服務端代碼中引入paho API(假設咱們的服務端用Java EE來實現),這時咱們的tomcat服務器也就能夠鏈接mqtt服務器了,而對於mqtt服務器來講,這個tomcat服務器跟Android手機是同樣的,它只是一個普通的客戶端,mqtt服務器甚至不知道鏈接它的是一臺手機仍是一臺部署了tomcat的Linux主機,mqtt服務器只知道有一臺設備請求發佈消息,那麼就把這條消息推送給訂閱了這一主題的設備,僅此而已,mqtt服務器、管理後臺服務器和終端的關係以下圖所示:

相關文章
相關標籤/搜索