2011年6月28日

突破 Whatsapp 限制 (三) 運作原理

註:由於作者是使用 iOS ,以下運作原理全以 iOS 為準。


簡化版:

Whatsapp 會在其伺服器上開通一個和用戶的電話號碼相連結的帳號並進行訊息推送。

當用戶啟動 Whatsapp 時,終端會自動連上伺服器。當伺服器收到狀態提示後,會將用戶的線上狀態顯示為”線上 (Online)”。並將儲存在伺服器上的未傳送訊息推送至終端。當伺服器送出訊息後,將會顯示兩個勾,即為”已傳送至終端” (並不代表已閱讀)。

Whatsapp 將會與電話本身的UDID進行配對後自行產生一組授權密碼,在推送訊息時將會先進行授權。



進階:



設備審查 Device Check:

首次開啟應用程序時,程式將會審查該設備是否可以使用 Whatsapp。在這裏,Whatsapp 會拒絕在 iPad 及 iPod Touch 中執行。

在 Whatsapp.app 中的 info.plist 中,詳細列明了 Whatsapp 將會如何檢查設備是否可執行程序,包括:

  • UIRequiredDeviceCapabilities: telephony = 1;
    設備需要具備電話功能;
  • - UIDeviceFamily (Array): 0: 1;
    設備必需為 iPhone 或 iPod Touch (1); ((2) 為 iPad)
  • - LSRequiresIPhoneOS = 1;
    設備必需為 iPhone (過濾 iPod Touch)
  • - MinimumOSVersion = 3.1;
    iOS 版本須為 3.1 或以上

聰明的你可能想到了,透過修改 info.plist 的設定可以有機會改變程式的審查程序。在此須留意,你不可以單靠修改 info.plist 來改變程式的審查程序。例如 UIDeviceFamily 在 info.plist 中修改是沒有用的。

在 iOS 上, iPhone 及 iPod Touch 是屬於同一系列,而 iPad 是屬於另一種設備。所以透過 info.plist 的修改是可以令程式接受 iPod Touch,但不能令程序放棄檢查 iPad 。

另要說明,設備審查只會在首次啟動程序時才會執行。


註冊:

當設備通過 Device Check 之後,程序便會嘗試連接伺服器,傳送設備的識別碼 (Unique Device Identifier, UDID) 給予伺服器。同時程序要求用戶提供一個電話號碼作為登記。伺服器將會自動傳送一個三位數字的短訊給予該登記電話號碼,用戶輸入該數字之後,此電話號碼將會與該設備的識別碼 UDID 綁定,並產生一組22位的64-bit授權密碼作為鎖匙,用作將來與伺服器通訊之用。

伺服器將會為此電話號碼註冊一個 Jabber ID (格式很像一個電郵地址),並為此 Jabber ID 設定用戶名稱及 Status (預設為 “Hey there! I am using Whatsapp.”)。

所有登入資訊都被放在 Library > Preferences > net.whatsapp.WhatsApp.Plist 裏面。


登入 / 登出:

當每一次程式進行啟動時,會使用 Jabber ID 登入伺服器,並傳送設備的 UDID 以及在註冊時產生的授權密碼往伺服器。伺服器首先會核對 UDID 是否和登記時一致,如否,則強制終端重新進入首次運行的程序,用戶需要重新註冊和綁定電話號碼。如是,則再檢查授權密碼是否正確,如正確則可登入伺服器。此時,該用戶的 Online Status 為 “On”。

當 Whatsapp 被關閉時 (在 iOS 4 或以上,按 home 離開並非關閉程式,人手或系統關閉程式才算), Whatsapp 將會傳送離線通知給予伺服器,伺服器將用戶的 Online Status 轉為 “Off”。而在 iOS 上,如果終端沒有傳回 online 通知 (在背景應用時是不會傳回 online 通知的),伺服器的 Online Status 會 time out,轉為 offline (時間沒有驗證)

在 Android 及其他設備時,似乎 timeout 機制被 Android 強大的 Multitasking 避過了。所以 Android 用戶會因此長期上線 (除非用戶經常使用 Advanced Application Killer) 。

會有朋友想問,我可否隱身?答案是否定的。留意這並非 MSN ,Whatsapp 不知有多想人們知道你經常開啟 Whatsapp ,又怎會讓你隱身呢?


識別 Whatsapp 用家:

Whatsapp 會要求使用用戶的電話簿,並將電話號碼傳至伺服器作搜尋。如該電話已經登記,伺服器會傳回該電話的 Jabber ID 給予用戶,並和該用戶的電話簿作連結。

Jabber ID 會有 Online / Offline 以及 Status 的資訊,所以當一個朋友已登記 Whatsapp 的話,你便可以看見對方何時上線,以及最新的 Status 了。

Whatsapp 也會使用電話簿的頭像以及姓名,不會顯示 Jabber ID 以及登記用戶名稱以免用戶混淆。


傳送及接收訊息:

用戶在 Whatsapp 中向另一個用戶傳送短訊,是使用 Jabber ID 作為溝通的。傳送及接收訊息的過程,技術上和我們過往使用的 ICQ 及 MSN 沒有分別。使用 Jabber (現稱 XMPP) 標準作為通訊。

值得提兩件事:

推送通知 - 當伺服器得知收件人並沒有上線的時候,便會使用 Apple 的推送通知傳出該訊息。因為伺服器並不知道該收件人在你的通訊錄上的名字,所以該推送將使用收件人所登記的名字。而 Apple 對於每一個應用程式的推送通知上限只得一個,所以當收件人沒有上線,而且並沒有網絡連接的時候,收件人只能收到最後一個訊息的推送。

訊息接收狀態 - 當訊息已傳送往伺服器後,該訊息在寄件人的介面上將會有一個勾,表示 “已傳送往伺服器”。 收件人如果沒有上線,訊息將會儲存在伺服器中。究竟伺服器能儲存多少訊息?以數量還是以容量計算?不得而知。

當收件人上線的時候,伺服器將會把所有的訊息推送給收件人,成功後,將會通知寄件人已將訊息送達收件人的設備中,寄件人的介面上將會有兩個勾,表示 “已傳送給收件人”。

留意,兩個勾並不代表收件人已閱讀了寄件人的短訊。在其他競爭對手中,例如 Kik Messenger ,除了 “Sent” 和“Delivered” 之外,還多了一樣 “Read” ,代表收件人已閱讀該訊息。這是 Whatsapp 美中不足的地方。

所有已接收的短訊訊息將會被儲存在 Documents > ChatStorage.sqlite 中,想備份的朋友留意了。

而所有音訊、圖片、短片,將會被儲存在 Library > Media 中,這些多媒體檔案將會根據寄件人的 Jabber ID 來存檔。


總結:

由此看出, Whatsapp 所運用的技術和其他 IM 沒多大分別,門檻相對不高,但對於伺服器穩定性的要求非常高,相信 Whatsapp 團隊為此下了一番苦功。

而直接使用電話簿這招,在眾多同類型程式中,Whatsapp 是用得最漂亮的一個了。

3 則留言:

匿名 說...

先感謝大大對於whatsapp的研究與分享!

正好本人最近也對於whatsapp的一些問題很好奇,
正好在網絡上找到大大這篇文章,真的獲益良多。

我比較好奇的是whatsapp的用戶在線狀態是不是都能準確(比較準確)的呈現用戶的狀態。

例子1:
好友A他正在跟本人在聊天,但是他的狀態是顯示“最後閱讀時間xx”

例子2:
好友B宣稱他已經睡覺了,但是我發現他的狀態卻一直是在線的。以我的理解,只要一直都在whatsapp裏面沒按home鍵跳出桌面,或者沒讓手機自動鎖屏,whatsapp是會一直顯示那位用家在線的,不管當時他是否再跟你聊天

一直以來我都覺得whatsapp的狀態欄還蠻准的,只是最近某些例子讓我疑惑了

望大大能指點一下迷津,謝謝!

匿名 說...

抱歉,想請教一件事情。
原本已將what's app刪除且移除,但最近從別人的手機發現狀態在一天前被修改。這樣是不是代表有人在使用?是被盜用的意思嗎?

匿名 說...

我的HTC Sensation開啟通知功能~~~
但是朋友傳app訊息給我手機卻不會響
請問是怎麼回事呢?