Telegram iOS 端架構(gòu)淺談

Telegram

Telegram 作為一款風(fēng)靡全球的社交軟件,最大的特點(diǎn)就是信息加密不受監(jiān)管。中東炮火中的火箭手在用,香港 DU 場(chǎng) xi qian 的大佬也在用......這種安全私密、不受監(jiān)管的特點(diǎn)非常符合區(qū)塊鏈業(yè)務(wù)的需求,所以大部分區(qū)塊鏈軟件會(huì)基于 Telegram 做二次研發(fā)。當(dāng)然還有各種各樣有安全需求的業(yè)務(wù)會(huì)考慮在 Telegram 的基礎(chǔ)上做研發(fā)。

Telegram

開(kāi)源

除了保證聊天的安全加密,Telegram 全平臺(tái)也是開(kāi)源的,包括 Server、iOS、Android 都可以在 Github 看到相應(yīng)的源碼。在 Telegram 后臺(tái)注冊(cè)一個(gè)賬號(hào),就可以開(kāi)始開(kāi)發(fā)工作了。本文主要談一下對(duì) Telegram 的 iOS 源碼的理解。

底層數(shù)據(jù)庫(kù)結(jié)構(gòu)

如下圖,通過(guò)底層數(shù)據(jù)庫(kù)結(jié)構(gòu),我們可以了解 Telegram 主要業(yè)務(wù)是:群聊、單聊(普通/私密)、聯(lián)系人、消息收發(fā)、媒體緩存等。

Telegram 數(shù)據(jù)庫(kù)結(jié)構(gòu)

消息機(jī)制

Telegram 消息是通過(guò)長(zhǎng)鏈接收發(fā)的,做了非對(duì)稱加密處理,保證不會(huì)在傳輸過(guò)程中被劫持破解。服務(wù)器只做消息的轉(zhuǎn)發(fā),并不保存用戶的聊天信息。

iOS 端使用的 MTProto 協(xié)議進(jìn)行聊天加密,2.0 版本的協(xié)議如下:

MTProto

消息接收的過(guò)程如下:

TCP 接收消息的流程

消息結(jié)構(gòu)

_uid:577499321
_contactId:1236149230
_flags:8
_phoneNumber:8613763203217
_phoneNumberHash:-673666323598709087
_firstName:pauley
_LastName:Haha
_photoUrlSmall:5_852733294_208097_6526069910252166177
_photoUrlBig:5_852733894_20823229_5128008587494466111

消息構(gòu)建

下面以文本消息為例,梳理下消息構(gòu)建流程。TGPreparedTextMessage 是準(zhǔn)備要發(fā)送的消息格式封裝類,生成需要的消息 ID 等信息。 然后轉(zhuǎn)換為 TGMessage 通過(guò) TCP 通道發(fā)送到 Server,同時(shí)寫入本地?cái)?shù)據(jù)庫(kù)并通過(guò) KVO 的方式更新聊天視圖。

TGPreparedTextMessage *preparedMessage = [[TGPreparedTextMessage alloc] initWithText:[NSString stringWithFormat:@"%d", i] replyMessage:nil disableLinkPreviews:NO parsedWebpage:nil entities:nil botContextResult:nil replyMarkup:nil];

if (preparedMessage.randomId == 0)
{
    int64_t randomId = 0;
    arc4random_buf(&randomId, sizeof(randomId));
    preparedMessage.randomId = randomId;
}

if (preparedMessage.mid == 0)
    preparedMessage.mid = [[TGDatabaseInstance() generateLocalMids:1][0] intValue];
preparedMessage.date = (int)[[TGTeleboxNetworking instance] approximateRemoteTime];

TGMessage *message = [preparedMessage message];

message.cid = [self peerId];
message.fromUid = 531399335;
message.toUid = 577499201;
message.date = 1531396567;
message.flags = 2;

[TGDatabaseInstance() transactionAddMessages:@[message] updateConversationDatas:@{} notifyAdded:true];

[ActionStageInstance() dispatchResource:[[NSString alloc] initWithFormat:@"/tg/conversation/(%lld)/messages", [self peerId]] resource:[[SGraphObjectNode alloc] initWithObject:@[message]]];

聊天 Cell 組建

高度組件化的聊天 Cell,通過(guò)一系列圖片、文本、按鈕、頭像、背景等基礎(chǔ)組建組裝。為了提高性能,視圖的渲染使用的 Core Grahics 框架繪制。所以如果需要自定義布局,需要在 layout 方法中 resize 視圖。整個(gè)聊天 Cell 的組建流程如下圖:

聊天 Cell 組建

核心類和方法

  • 處理接收消息類
MTRequestMessageService、TGUpdateMessageService
  • 獲取 User
 TGUser *databaseUser = [[TGDatabase instance] loadUser:(int)(it->first)];
  • 消息數(shù)據(jù)構(gòu)建類:
TGPreparedTextMessage
  • 數(shù)據(jù)庫(kù)寫入:
[TGDatabaseInstance() transactionAddMessages:@[message] updateConversationDatas:@{} notifyAdded:true];
  • 數(shù)據(jù)更新:
[ActionStageInstance() dispatchResource:[[NSString alloc] 
initWithFormat:@"/tg/conversation/(%@)/messages", [self _conversationIdPathComponent]] resource:[[SGraphObjectNode alloc] initWithObject:addToDatabaseMessages]];

相關(guān)鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評(píng)論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,676評(píng)論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 176,730評(píng)論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,118評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,873評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,266評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評(píng)論 3 443
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,482評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,036評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,846評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,025評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,279評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 34,684評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 35,953評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,751評(píng)論 3 394
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,016評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容