1、前言
本文要分享的消息推送指的是當(dāng)iOS端APP被關(guān)閉或者處于后臺(tái)時(shí),還能收到消息/信息/指令的能力。
這種在APP處于后臺(tái)或關(guān)閉情況下的消息推送能力,通常在以下場(chǎng)景下非常有用:
1)IM即時(shí)通訊聊天應(yīng)用:聊天消息通知、音視頻聊天呼叫等,典型代表有:微信、QQ、易信、米聊、釘釘、Whatsup、Line;
2)新聞資訊應(yīng)用:最新資訊通知等,典型代碼有:網(wǎng)易新聞客戶端、騰訊新聞客戶端;
3)SNS社交應(yīng)用:轉(zhuǎn)發(fā)/關(guān)注/贊等通知,典型代表有:微博、知乎;
4)郵箱客戶端:新郵件通知等,典型代表有:QQ郵箱客戶端、Foxmail客戶端、網(wǎng)易郵箱大師;
5)金融支付應(yīng)用:收款通知、轉(zhuǎn)賬通知等,典型代表有:支付寶、各大銀行的手機(jī)銀行等;
.... ....
除了以上典型場(chǎng)景下,消息推送這種能力已經(jīng)被越來(lái)越多的APP作為基礎(chǔ)能力之一,因?yàn)橐苿?dòng)互聯(lián)網(wǎng)時(shí)代下,用戶的“全時(shí)在線”能力非常誘人和強(qiáng)大,能隨時(shí)隨地即時(shí)地將各種重要信息推送給用戶,無(wú)疑是非常有意義的。
眾所周之,iOS端的這項(xiàng)消息推送能力就是使用蘋果提供的APNs服務(wù)來(lái)實(shí)現(xiàn)(有些iOS小白開發(fā)者可能看到各種第3方的iOS端消息推送SDK,總會(huì)習(xí)慣性地認(rèn)為這是完全由第3方提供的能力,實(shí)際上同樣是使用APNs,只是封裝了一下而已)。目前介紹APNs消息推送的文章多討論的是手機(jī)端的實(shí)現(xiàn),而服務(wù)端的消息要怎么“推”出來(lái)這樣的文章,要么太老,要么只是介紹如何調(diào)用第3方的服務(wù)端SDK接口而已(如極光推廣、友盟推送、騰訊信鴿推送等)。所以本文趁著最近對(duì)項(xiàng)目組的老蘋果iOS推送進(jìn)行升級(jí)修改機(jī)會(huì),詳細(xì)查閱了最新蘋果的APNs接口文檔,同時(shí)為了避免重復(fù)造輪子(懶),在調(diào)研了一些開源常用的庫(kù)之后,選擇了Turo團(tuán)隊(duì)開發(fā)和維護(hù)的pushy開源工程來(lái)實(shí)現(xiàn)在Java服務(wù)端調(diào)用蘋果最新的APNs HTTP/2接口進(jìn)行消息推送,并借此文對(duì)Pushy的使用方法進(jìn)行了總結(jié)和記錄,希望對(duì)你用。
補(bǔ)充說(shuō)明:網(wǎng)上目前能查到的有關(guān)iOS端APNs消息推送的Java服務(wù)端代碼實(shí)現(xiàn),多是介紹如何使用Java-APNS這個(gè)工程,但這個(gè)工程以及類似的其它工程都很久沒有維護(hù)了,跟最新的蘋果APNs服務(wù)已經(jīng)很難匹配了。相較而言puhsy這個(gè)工程一直比較活躍,也對(duì)蘋果的最新APNs跟進(jìn)的比較及時(shí),因而本文作者在公司的項(xiàng)目進(jìn)行升級(jí)和重構(gòu)過(guò)程中,毫不猶豫的使用了pushy。
學(xué)習(xí)交流:
- 即時(shí)通訊開發(fā)交流3群:185926912 [推薦]
- 移動(dòng)端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動(dòng)端IM》
(本文同步發(fā)布于:http://www.52im.net/thread-1820-1-1.html)
2、相關(guān)文章
有關(guān)iOS客戶端APNs消息推送技術(shù)的介紹文章:
《iOS的推送服務(wù)APNs詳解:設(shè)計(jì)思路、技術(shù)原理及缺陷等》
《信鴿團(tuán)隊(duì)原創(chuàng):一起走過(guò) iOS10 上消息推送(APNS)的坑》
《了解iOS消息推送一文就夠:史上最全iOS Push技術(shù)詳解》
《移動(dòng)端實(shí)時(shí)消息推送技術(shù)淺析》
《掃盲貼:淺談iOS和Android后臺(tái)實(shí)時(shí)消息推送的原理和區(qū)別》
有關(guān)消息推送技術(shù)服務(wù)端架構(gòu)方面的文章:
《絕對(duì)干貨:基于Netty實(shí)現(xiàn)海量接入的推送服務(wù)技術(shù)要點(diǎn)》
《極光推送系統(tǒng)大規(guī)模高并發(fā)架構(gòu)的技術(shù)實(shí)踐分享》
《魅族2500萬(wàn)長(zhǎng)連接的實(shí)時(shí)消息推送架構(gòu)的技術(shù)實(shí)踐分享》
《專訪魅族架構(gòu)師:海量長(zhǎng)連接的實(shí)時(shí)消息推送系統(tǒng)的心得體會(huì)》
《一個(gè)基于長(zhǎng)連接的安全可擴(kuò)展的訂閱/推送服務(wù)實(shí)現(xiàn)思路》
《實(shí)踐分享:如何構(gòu)建一套高可用的移動(dòng)端消息推送系統(tǒng)?》
《Go語(yǔ)言構(gòu)建千萬(wàn)級(jí)在線的高并發(fā)消息推送系統(tǒng)實(shí)踐(來(lái)自360公司)》
《騰訊信鴿技術(shù)分享:百億級(jí)實(shí)時(shí)消息推送的實(shí)戰(zhàn)經(jīng)驗(yàn)》
《百萬(wàn)在線的美拍直播彈幕系統(tǒng)的實(shí)時(shí)推送技術(shù)實(shí)踐之路》
《京東京麥商家開放平臺(tái)的消息推送架構(gòu)演進(jìn)之路》
>> 更多同類文章 ……
3、提一下Android端的消息推送
論壇里做IM或消息推送服務(wù)的朋友都很清楚,相對(duì)于蘋果為iOS包辦好的APNs技術(shù),Android上的消息推送技術(shù)亂七八糟、一塌糊涂,原因是國(guó)內(nèi)的Android廠商將Android原生的GCM(現(xiàn)在叫FCM,跟iOS的APNs是類似的技術(shù))進(jìn)行了閹割,加上各廠商的省電策略、這全策略各不相同,導(dǎo)致為了實(shí)現(xiàn)IM和其它各種應(yīng)用中的后臺(tái)消息推送,不得不為了進(jìn)程保活、網(wǎng)絡(luò)保活搞出各種黑科技(當(dāng)然,自從Android 6.0發(fā)布以后,谷歌為了打擊這種不道德的行為,進(jìn)行了越來(lái)越嚴(yán)格的限制,保活黑科技越來(lái)越難搞了)。
國(guó)內(nèi)的廠商為了跟進(jìn)新版本Android的GCM(現(xiàn)在叫FCM),也都在搞自已的消息推送通道:小米手機(jī)有小米推送、魅族手機(jī)有魅族推送、華為手機(jī)有華為推送等等,開發(fā)者在放棄保活黑科技以后,只能一家一家接入各廠商的推送通道,而這這又涉到同一廠商的手機(jī)版本、不同廠商通道的自動(dòng)識(shí)別等,麻煩事亂到你無(wú)法想象,就連第3方推送服務(wù)也只能就范——一家一家接入(比如信鴿的《[資訊] 信鴿新版上線:號(hào)稱Android首家統(tǒng)一推送服務(wù)》)。
為了解決上述亂象,好消息是去年有政府背景的“統(tǒng)一推送聯(lián)盟”成立了(詳見《[資訊] 統(tǒng)一推送聯(lián)盟在京成立:結(jié)束國(guó)內(nèi)安卓生態(tài)混亂》),廣大Android開發(fā)者真是翹首以盼,但壞消息是好進(jìn)展并不順利(大家心知肚明啊,各廠商的利益不好均衡嘛),最近一次跟消息推送服務(wù)有關(guān)的活動(dòng)還是3個(gè)月前的《[資訊] 統(tǒng)一推送聯(lián)盟2018成員大會(huì)如期召開》。雖然進(jìn)展不大,但總算還是有希望,Android同行們?cè)俚鹊龋傆蠥ndroid端消息推送一統(tǒng)江湖的方案出現(xiàn)的那天。
當(dāng)然,本文主要是討論iOS端的消息推送,本節(jié)文字只是寫給Android端消息推送感興趣的同行看的,更多Android消息推送技術(shù)的文章,請(qǐng)前往:http://www.52im.net/forum.php?mod=collection&action=view&ctid=11
4、說(shuō)一說(shuō)為什么不使用第3方推送服務(wù)SDK?
目前主流的iOS第3方推送SDK有:友盟推送、極光推送、信鴿推送等。
使用第3方推送的優(yōu)點(diǎn)主要是:
1)簡(jiǎn)單:開箱即用,無(wú)需關(guān)注技術(shù)細(xì)節(jié);
2)統(tǒng)計(jì):提供了推送數(shù)據(jù)的統(tǒng)計(jì)能力等;
3)性能:無(wú)需關(guān)注性能負(fù)載,因?yàn)榈?方都幫你實(shí)現(xiàn)好了,你只要調(diào)用它的接口即可。
使用第3方推送的缺點(diǎn)也很明顯:
1)到達(dá)率:雖然第3方移動(dòng)端消息推送產(chǎn)品都宣傳到達(dá)率能夠達(dá)到 90%及以上,但是實(shí)際使用起來(lái),發(fā)現(xiàn)遠(yuǎn)遠(yuǎn)達(dá)不到;
2)實(shí)時(shí)性:第3方移動(dòng)端消息推送產(chǎn)品的推送通道是共用的,會(huì)面向多個(gè)推送客戶,如果某一個(gè)客戶PUSH推送量特別大,那么其他的移動(dòng)端消息推送消息實(shí)時(shí)性可能就會(huì)受到影響;
3)不可控:雖然各種技術(shù)細(xì)節(jié)無(wú)需你關(guān)注是個(gè)優(yōu)點(diǎn),但它也同時(shí)是個(gè)缺點(diǎn)——因?yàn)槟悴豢煽氐臇|西太多了,想要做一個(gè)定制化的需求就力不從心了;
4)被限流:因?yàn)榈?方的推送服務(wù)多是免費(fèi)提供,所以接口調(diào)用等都是有限制要求的(即使紙面上沒有說(shuō)出來(lái)),限流是一定要做的,不然這些成本誰(shuí)抗的住?
針對(duì)以上問(wèn)題,58同城團(tuán)隊(duì)在《58同城高性能移動(dòng)端消息推送技術(shù)架構(gòu)演進(jìn)之路》也有討論。
更為關(guān)鍵的是,如果是實(shí)現(xiàn)iOS的消息推送,蘋果官方提供的APNs服務(wù)已經(jīng)足夠簡(jiǎn)單,如果不是為了項(xiàng)目趕進(jìn)度或偷懶,自已來(lái)實(shí)現(xiàn)是更靠譜的選擇,簡(jiǎn)單的事情沒有必要復(fù)雜化,這也正是本文作者的選擇。
好了,言歸正傳,繼續(xù)聊回使用pushy實(shí)現(xiàn)iOS高性能推送這個(gè)話題。
5、APNs和Pushy
蘋果設(shè)備的消息推送是依靠蘋果的APNs(Apple Push Notification service)服務(wù)的,APNs的官方簡(jiǎn)介如下:
Apple Push Notification service (APNs) is the centerpiece of the remote notifications feature. It is a robust, secure, and highly efficient service for app developers to propagate information to iOS (and, indirectly, watchOS), tvOS, and macOS devices.
(如果英文看起來(lái)不方便,可以看看《iOS的推送服務(wù)APNs詳解:設(shè)計(jì)思路、技術(shù)原理及缺陷等》)
IOS設(shè)備(tvOS、macOS)上的所有消息推送都需要經(jīng)過(guò)APNs,APNs服務(wù)確實(shí)非常厲害,每天需要推送上百億的消息,可靠、安全、高效。就算是微信和QQ這種用戶級(jí)別的即時(shí)通訊app在程序沒有啟動(dòng)或者后臺(tái)運(yùn)行過(guò)程中也是需要使用APNs的(當(dāng)程序啟動(dòng)時(shí),使用自己建立的長(zhǎng)連接),只不過(guò)騰訊優(yōu)化了整條從他們服務(wù)器到蘋果服務(wù)器的線路而已,所以覺得推送要快(參考知乎)。
項(xiàng)目組老的蘋果推送服務(wù)使用的是蘋果以前的基于二進(jìn)制socket的APNs,同時(shí)使用的是一個(gè)javapns的開源庫(kù),這個(gè)javapns貌似效果不是很好,在網(wǎng)上也有人有過(guò)討論。javapns現(xiàn)在也停止維護(hù)DEPRECATED掉了。作者建議轉(zhuǎn)向基于蘋果新APNs服務(wù)的庫(kù)。
蘋果新APNs基于HTTP/2,通過(guò)連接復(fù)用,更加高效,當(dāng)然還有其它方面的優(yōu)化和改善,可以參考APNs的一篇介紹,講解的比較清楚。
再說(shuō)一下我們使用的Pushy,官方簡(jiǎn)介如下:
Pushy is a Java library for sending APNs (iOS, macOS, and Safari) push notifications. It is written and maintained by the engineers at Turo......We believe that Pushy is already the best tool for sending APNs push notifications from Java applications, and we hope you'll help us make it even better via bug reports and pull requests.
Pushy的文檔和說(shuō)明很全,討論也很活躍,作者基本有問(wèn)必答,大部分疑問(wèn)都可以找到答案,使用難度也不大。
6、在Java端使用Pushy進(jìn)行APNs消息推送
6.1 首先加入包
6.2 身份認(rèn)證
蘋果APNs提供了兩種認(rèn)證的方式:基于JWT的身份信息token認(rèn)證和基于證書的身份認(rèn)證。Pushy也同樣支持這兩種認(rèn)證方式,這里我們使用證書認(rèn)證方式,關(guān)于token認(rèn)證方式可以查看Pushy的文檔。
如何獲取蘋果APNs身份認(rèn)證證書可以查考官方文檔。
6.3 Pushy使用
ps:這里的setClientCredentials函數(shù)也可以支持傳入一個(gè)InputStream和證書密碼。
同時(shí)也可以通過(guò)setApnsServer函數(shù)來(lái)指定是開發(fā)環(huán)境還是生產(chǎn)環(huán)境:
Pushy是基于Netty的,通過(guò)ApnsClientBuilder我們可以根據(jù)需要來(lái)修改ApnsClient的連接數(shù)和EventLoopGroups的線程數(shù):
關(guān)于連接數(shù)和EventLoopGroup線程數(shù)官網(wǎng)有如下的說(shuō)明,簡(jiǎn)單來(lái)說(shuō),不要配置EventLoopGroups的線程數(shù)超過(guò)APNs連接數(shù):
Because connections are bound to a single event loop (which is bound to a single thread), it never makes sense to give an ApnsClient more threads in an event loop than concurrent connections. A client with an eight-thread EventLoopGroup that is configured to maintain only one connection will use one thread from the group, but the other seven will remain idle. Opening a large number of connections on a small number of threads will likely reduce overall efficiency by increasing competition for CPU time.
關(guān)于消息的推送,注意一定要使用異步操作,Pushy發(fā)送消息會(huì)返回一個(gè)Netty Future對(duì)象,通過(guò)它可以拿到消息發(fā)送的情況:
APNs服務(wù)器可以保證同時(shí)發(fā)送1500條消息,當(dāng)超過(guò)這個(gè)限制時(shí),Pushy會(huì)緩存消息,所以我們不必?fù)?dān)心異步操作發(fā)送的消息過(guò)多。
當(dāng)我們的消息非常多,達(dá)到上億時(shí),我們也得做一些控制,避免緩存過(guò)大,內(nèi)存不足,Pushy給出了使用Semaphore的解決方法:
The APNs server allows for (at the time of this writing) 1,500 notifications in flight at any time. If we hit that limit, Pushy will buffer notifications automatically behind the scenes and send them to the server as in-flight notifications are resolved.
In short, asynchronous operation allows Pushy to make the most of local resources (especially CPU time) by sending notifications as quickly as possible.
以上僅是Pushy的基本用法,在我們的生產(chǎn)環(huán)境中情況可能會(huì)更加復(fù)雜,我們可能需要知道什么時(shí)候所有推送都完成了,可能需要對(duì)推送成功消息進(jìn)行計(jì)數(shù),可能需要防止內(nèi)存不足,也可能需要對(duì)不同的發(fā)送結(jié)果進(jìn)行不同處理....
不多說(shuō),上代碼(請(qǐng)看下節(jié)...)。
7、Pushy的最佳實(shí)踐
參考Pushy的官方最佳實(shí)踐,我們加入了如下操作:
通過(guò)Semaphore來(lái)進(jìn)行流控,防止緩存過(guò)大,內(nèi)存不足;
通過(guò)CountDownLatch來(lái)標(biāo)記消息是否發(fā)送完成;
使用AtomicLong完成匿名內(nèi)部類operationComplete方法中的計(jì)數(shù);
使用Netty的Future對(duì)象進(jìn)行消息推送結(jié)果的判斷。
具體用法參考如下代碼:
publicclassIOSPush {
privatestaticfinalLogger logger = LoggerFactory.getLogger(IOSPush.class);
privatestaticfinalApnsClient apnsClient = null;
privatestaticfinalSemaphore semaphore = newSemaphore(10000);
publicvoidpush(finalList deviceTokens, String alertTitle, String alertBody) {
longstartTime = System.currentTimeMillis();
if(apnsClient == null) {
try{
EventLoopGroup eventLoopGroup = newNioEventLoopGroup(4);
apnsClient = newApnsClientBuilder().setApnsServer(ApnsClientBuilder.DEVELOPMENT_APNS_HOST)
.setClientCredentials(newFile("/path/to/certificate.p12"), "p12-file-password")
.setConcurrentConnections(4).setEventLoopGroup(eventLoopGroup).build();
} catch(Exception e) {
logger.error("ios get pushy apns client failed!");
e.printStackTrace();
}
}
longtotal = deviceTokens.size();
finalCountDownLatch latch = newCountDownLatch(deviceTokens.size());
finalAtomicLong successCnt = newAtomicLong(0);
longstartPushTime = System.currentTimeMillis();
for(String deviceToken : deviceTokens) {
ApnsPayloadBuilder payloadBuilder = newApnsPayloadBuilder();
payloadBuilder.setAlertBody(alertBody);
payloadBuilder.setAlertTitle(alertTitle);
String payload = payloadBuilder.buildWithDefaultMaximumLength();
finalString token = TokenUtil.sanitizeTokenString(deviceToken);
SimpleApnsPushNotification pushNotification = newSimpleApnsPushNotification(token, "com.example.myApp", payload);
try{
semaphore.acquire();
} catch(InterruptedException e) {
logger.error("ios push get semaphore failed, deviceToken:{}", deviceToken);
e.printStackTrace();
}
finalFuture> future = apnsClient.sendNotification(pushNotification);
future.addListener(newGenericFutureListener>() {
@Override
publicvoidoperationComplete(Future pushNotificationResponseFuture) throwsException {
if(future.isSuccess()) {
finalPushNotificationResponse response = future.getNow();
if(response.isAccepted()) {
successCnt.incrementAndGet();
} else{
Date invalidTime = response.getTokenInvalidationTimestamp();
logger.error("Notification rejected by the APNs gateway: "+ response.getRejectionReason());
if(invalidTime != null) {
logger.error("\t…and the token is invalid as of "+ response.getTokenInvalidationTimestamp());
}
}
} else{
logger.error("send notification device token={} is failed {} ", token, future.cause().getMessage());
}
latch.countDown();
semaphore.release();
}
});
}
try{
latch.await(20, TimeUnit.SECONDS);
} catch(InterruptedException e) {
logger.error("ios push latch await failed!");
e.printStackTrace();
}
longendPushTime = System.currentTimeMillis();
logger.info("test pushMessage success. [共推送"+ total + "個(gè)][成功"+ (successCnt.get()) + "個(gè)],
totalcost= " + (endPushTime - startTime) + ", pushCost=" + (endPushTime - startPushTime));
}
}
關(guān)于多線程調(diào)用client:
Pushy ApnsClient是線程安全的,可以使用多線程來(lái)調(diào)用。
關(guān)于創(chuàng)建多個(gè)client:
創(chuàng)建多個(gè)client是可以加快發(fā)送速度的,但是提升并不大,作者建議:
ApnsClient instances are designed to stick around for a long time. They're thread-safe and can be shared between many threads in a large application. We recommend creating a single client (per APNs certificate/key), then keeping that client around for the lifetime of your application.
關(guān)于APNs響應(yīng)信息(錯(cuò)誤信息):
可以查看APNs官網(wǎng)的error code表格,了解出錯(cuò)情況,及時(shí)調(diào)整。
8、來(lái)看看Pushy的性能
作者在Google討論組中說(shuō)Pushy推送可以單核單線程達(dá)到10k/s-20k/s,如下圖所示:
▲ 作者關(guān)于創(chuàng)建多client的建議及Pushy性能描述
但是可能是網(wǎng)絡(luò)或其他原因,我的測(cè)試結(jié)果沒有這么好,把測(cè)試結(jié)果貼出來(lái),僅供參考(時(shí)間ms)。
ps:由于是測(cè)試,沒有大量的設(shè)備可以用于群發(fā)推送測(cè)試,所以以往一個(gè)設(shè)備發(fā)送多條推送替代。這里短時(shí)間往一個(gè)設(shè)備發(fā)送大量的推送,APNs會(huì)報(bào)TooManyRequests錯(cuò)誤,Too many requests were made consecutively to the same device token。所以會(huì)有少量消息無(wú)法發(fā)出。
ps:這里的推送時(shí)間,沒有加上client初始化的時(shí)間。
ps:消息推送時(shí)間與被推消息的大小有關(guān)系,這里我在測(cè)試時(shí)沒有控制消息變量(都是我瞎填的,都是很短的消息)所以數(shù)據(jù)僅供參考。
關(guān)于Pushy性能優(yōu)化也可以看看官網(wǎng)作者的建議:Threads, concurrent connections, and performance
大家有測(cè)試的數(shù)據(jù)也可以分享出來(lái)一起討論一下。
8、思考和小結(jié)
蘋果APNs一直在更新優(yōu)化,一直在擁抱新技術(shù)(HTTP/2,JWT等),是一個(gè)非常了不起的服務(wù)。
自己來(lái)直接調(diào)用APNs服務(wù)來(lái)達(dá)到生成環(huán)境要求還是有點(diǎn)困難。Turo給我們提供了一個(gè)很好的Java庫(kù):Pushy。Pushy還有一些其他的功能與用法(Metrics、proxy、Logging...),總體來(lái)說(shuō)還是非常不錯(cuò)的。
同時(shí)感覺我們使用Pushy還可以調(diào)優(yōu)...
附錄:更多消息推送技術(shù)文章
[1] 有關(guān)IM/推送技術(shù)原理和服務(wù)端架構(gòu)等:
《iOS的推送服務(wù)APNs詳解:設(shè)計(jì)思路、技術(shù)原理及缺陷等》
《信鴿團(tuán)隊(duì)原創(chuàng):一起走過(guò) iOS10 上消息推送(APNS)的坑》
《Android端消息推送總結(jié):實(shí)現(xiàn)原理、心跳保活、遇到的問(wèn)題等》
《掃盲貼:認(rèn)識(shí)MQTT通信協(xié)議》
《一個(gè)基于MQTT通信協(xié)議的完整Android推送Demo》
《IBM技術(shù)經(jīng)理訪談:MQTT協(xié)議的制定歷程、發(fā)展現(xiàn)狀等》
《求教android消息推送:GCM、XMPP、MQTT三種方案的優(yōu)劣》
《移動(dòng)端實(shí)時(shí)消息推送技術(shù)淺析》
《掃盲貼:淺談iOS和Android后臺(tái)實(shí)時(shí)消息推送的原理和區(qū)別》
《絕對(duì)干貨:基于Netty實(shí)現(xiàn)海量接入的推送服務(wù)技術(shù)要點(diǎn)》
《移動(dòng)端IM實(shí)踐:谷歌消息推送服務(wù)(GCM)研究(來(lái)自微信)》
《為何微信、QQ這樣的IM工具不使用GCM服務(wù)推送消息?》
《極光推送系統(tǒng)大規(guī)模高并發(fā)架構(gòu)的技術(shù)實(shí)踐分享》
《從HTTP到MQTT:一個(gè)基于位置服務(wù)的APP數(shù)據(jù)通信實(shí)踐概述》
《魅族2500萬(wàn)長(zhǎng)連接的實(shí)時(shí)消息推送架構(gòu)的技術(shù)實(shí)踐分享》
《專訪魅族架構(gòu)師:海量長(zhǎng)連接的實(shí)時(shí)消息推送系統(tǒng)的心得體會(huì)》
《深入的聊聊Android消息推送這件小事》
《基于WebSocket實(shí)現(xiàn)Hybrid移動(dòng)應(yīng)用的消息推送實(shí)踐(含代碼示例)》
《一個(gè)基于長(zhǎng)連接的安全可擴(kuò)展的訂閱/推送服務(wù)實(shí)現(xiàn)思路》
《實(shí)踐分享:如何構(gòu)建一套高可用的移動(dòng)端消息推送系統(tǒng)?》
《Go語(yǔ)言構(gòu)建千萬(wàn)級(jí)在線的高并發(fā)消息推送系統(tǒng)實(shí)踐(來(lái)自360公司)》
《騰訊信鴿技術(shù)分享:百億級(jí)實(shí)時(shí)消息推送的實(shí)戰(zhàn)經(jīng)驗(yàn)》
《百萬(wàn)在線的美拍直播彈幕系統(tǒng)的實(shí)時(shí)推送技術(shù)實(shí)踐之路》
《京東京麥商家開放平臺(tái)的消息推送架構(gòu)演進(jìn)之路》
《了解iOS消息推送一文就夠:史上最全iOS Push技術(shù)詳解》
《基于APNs最新HTTP/2接口實(shí)現(xiàn)iOS的高性能消息推送(服務(wù)端篇)》
>> 更多同類文章 ……
[2] 有關(guān)IM/消息推送的通信格式、協(xié)議的選擇等:
《Protobuf通信協(xié)議詳解:代碼演示、詳細(xì)原理介紹等》
《一個(gè)基于Protocol Buffer的Java代碼演示》
《簡(jiǎn)述傳輸層協(xié)議TCP和UDP的區(qū)別》
《為什么QQ用的是UDP協(xié)議而不是TCP協(xié)議?》
《移動(dòng)端即時(shí)通訊協(xié)議選擇:UDP還是TCP?》
《如何選擇即時(shí)通訊應(yīng)用的數(shù)據(jù)傳輸格式》
《強(qiáng)列建議將Protobuf作為你的即時(shí)通訊應(yīng)用數(shù)據(jù)傳輸格式》
《全方位評(píng)測(cè):Protobuf性能到底有沒有比JSON快5倍?》
《移動(dòng)端IM開發(fā)需要面對(duì)的技術(shù)問(wèn)題(含通信協(xié)議選擇)》
《簡(jiǎn)述移動(dòng)端IM開發(fā)的那些坑:架構(gòu)設(shè)計(jì)、通信協(xié)議和客戶端》
《理論聯(lián)系實(shí)際:一套典型的IM通信協(xié)議設(shè)計(jì)詳解》
《58到家實(shí)時(shí)消息系統(tǒng)的協(xié)議設(shè)計(jì)等技術(shù)實(shí)踐分享》
《詳解如何在NodeJS中使用Google的Protobuf》
《技術(shù)掃盲:新一代基于UDP的低延時(shí)網(wǎng)絡(luò)傳輸層協(xié)議——QUIC詳解》
《金蝶隨手記團(tuán)隊(duì)分享:還在用JSON? Protobuf讓數(shù)據(jù)傳輸更省更快(原理篇)》
《金蝶隨手記團(tuán)隊(duì)分享:還在用JSON? Protobuf讓數(shù)據(jù)傳輸更省更快(實(shí)戰(zhàn)篇)》
>> 更多同類文章 ……
[3] 有關(guān)Android端IM/消息推送的心跳保活處理等:
《應(yīng)用保活終極總結(jié)(一):Android6.0以下的雙進(jìn)程守護(hù)保活實(shí)踐》
《應(yīng)用保活終極總結(jié)(二):Android6.0及以上的保活實(shí)踐(進(jìn)程防殺篇)》
《應(yīng)用保活終極總結(jié)(三):Android6.0及以上的保活實(shí)踐(被殺復(fù)活篇)》
《Android進(jìn)程保活詳解:一篇文章解決你的所有疑問(wèn)》
《Android端消息推送總結(jié):實(shí)現(xiàn)原理、心跳保活、遇到的問(wèn)題等》
《深入的聊聊Android消息推送這件小事》
《為何基于TCP協(xié)議的移動(dòng)端IM仍然需要心跳保活機(jī)制?》
《微信團(tuán)隊(duì)原創(chuàng)分享:Android版微信后臺(tái)保活實(shí)戰(zhàn)分享(進(jìn)程保活篇)》
《微信團(tuán)隊(duì)原創(chuàng)分享:Android版微信后臺(tái)保活實(shí)戰(zhàn)分享(網(wǎng)絡(luò)保活篇)》
《移動(dòng)端IM實(shí)踐:實(shí)現(xiàn)Android版微信的智能心跳機(jī)制》
《移動(dòng)端IM實(shí)踐:WhatsApp、Line、微信的心跳策略分析》
>> 更多同類文章 ……
(本文同步發(fā)布于:http://www.52im.net/thread-1820-1-1.html)