適合新手:從零開(kāi)發(fā)一個(gè)IM服務(wù)端(基于Netty,有完整源碼)
Posted on 2019-10-09 14:49 Jack Jiang 閱讀(2200) 評(píng)論(0) 編輯 收藏0、引言
站長(zhǎng)提示:本文適合IM新手閱讀,但最好有一定的網(wǎng)絡(luò)編程經(jīng)驗(yàn),必竟實(shí)踐性的代碼上手就是網(wǎng)絡(luò)編程。如果你對(duì)網(wǎng)絡(luò)編程,以及IM的一些理論知識(shí)知之甚少,請(qǐng)務(wù)必首先閱讀:《新手入門一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM》,該文為IM小白分類整理了詳盡的理論資料,請(qǐng)按需補(bǔ)充相關(guān)知識(shí)。
配套源碼:本文寫的比較淺顯但不太易懂,建議結(jié)合代碼一起來(lái)讀,文章配套的完整源碼 請(qǐng)從本文文末 “11、完整源碼下載” 處下載!
學(xué)習(xí)交流:
- 即時(shí)通訊/推送技術(shù)開(kāi)發(fā)交流5群:215477170 [推薦]
- 移動(dòng)端IM開(kāi)發(fā)入門文章:《新手入門一篇就夠:從零開(kāi)發(fā)移動(dòng)端IM》
(本文同步發(fā)布于:http://www.52im.net/thread-2768-1-1.html)
1、內(nèi)容概述
首先講講IM(即時(shí)通訊)技術(shù)可以用來(lái)做什么:
1)聊天:qq、微信;
2)直播:斗魚(yú)直播、抖音;
3)實(shí)時(shí)位置共享、游戲多人互動(dòng)等等。
可以說(shuō)幾乎所有高實(shí)時(shí)性的應(yīng)用場(chǎng)景都需要用到IM技術(shù)。
本篇將帶大家從零開(kāi)始搭建一個(gè)輕量級(jí)的IM服務(wù)端。
麻雀雖小,五臟俱全,我們搭建的IM服務(wù)端實(shí)現(xiàn)以下功能:
1)一對(duì)一的文本消息、文件消息通信;
2)每個(gè)消息有“已發(fā)送”/“已送達(dá)”/“已讀”回執(zhí);
3)存儲(chǔ)離線消息;
4)支持用戶登錄,好友關(guān)系等基本功能;
5)能夠方便地水平擴(kuò)展。
通過(guò)這個(gè)項(xiàng)目能學(xué)到很多后端必備知識(shí):
1)rpc通信;
2)數(shù)據(jù)庫(kù);
3)緩存;
4)消息隊(duì)列;
5)分布式、高并發(fā)的架構(gòu)設(shè)計(jì);
6)docker部署。
2、相關(guān)文章
- 《開(kāi)源移動(dòng)端IM技術(shù)框架MobileIMSDK》(* 推薦)
- 《自已開(kāi)發(fā)IM有那么難嗎?手把手教你自擼一個(gè)Andriod版簡(jiǎn)易IM (有源碼)》
- 《一種Android端IM智能心跳算法的設(shè)計(jì)與實(shí)現(xiàn)探討(含樣例代碼)》
- 《手把手教你用Netty實(shí)現(xiàn)網(wǎng)絡(luò)通信程序的心跳機(jī)制、斷線重連機(jī)制》
- 《NIO框架入門(一):服務(wù)端基于Netty4的UDP雙向通信Demo演示 [附件下載]》
- 《NIO框架入門(二):服務(wù)端基于MINA2的UDP雙向通信Demo演示 [附件下載]》
- 《NIO框架入門(三):iOS與MINA2、Netty4的跨平臺(tái)UDP雙向通信實(shí)戰(zhàn) [附件下載]》
- 《NIO框架入門(四):Android與MINA2、Netty4的跨平臺(tái)UDP雙向通信實(shí)戰(zhàn) [附件下載]》
- 《一個(gè)WebSocket實(shí)時(shí)聊天室Demo:基于node.js+socket.io [附件下載]》
相關(guān)IM架構(gòu)方面的文章:
- 《淺談IM系統(tǒng)的架構(gòu)設(shè)計(jì)》
- 《簡(jiǎn)述移動(dòng)端IM開(kāi)發(fā)的那些坑:架構(gòu)設(shè)計(jì)、通信協(xié)議和客戶端》
- 《一套海量在線用戶的移動(dòng)端IM架構(gòu)設(shè)計(jì)實(shí)踐分享(含詳細(xì)圖文)》
- 《一套原創(chuàng)分布式即時(shí)通訊(IM)系統(tǒng)理論架構(gòu)方案》
- 《從零到卓越:京東客服即時(shí)通訊系統(tǒng)的技術(shù)架構(gòu)演進(jìn)歷程》
- 《蘑菇街即時(shí)通訊/IM服務(wù)器開(kāi)發(fā)之架構(gòu)選擇》
- 《一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計(jì)實(shí)踐》
3、消息通信
3.1 文本消息
我們先從最簡(jiǎn)單的特性開(kāi)始實(shí)現(xiàn):一個(gè)普通消息的發(fā)送。
消息格式如下:
message ChatMsg{
id= 1;
//消息id
fromId = Alice
//發(fā)送者userId
destId = Bob
//接收者userId
msgBody = hello
//消息體
}
如上圖,我們現(xiàn)在有兩個(gè)用戶:Alice和Bob連接到了服務(wù)器,當(dāng)Alice發(fā)送消息message(hello)給Bob,服務(wù)端接收到消息,根據(jù)消息的destId進(jìn)行轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)給Bob。
3.2 發(fā)送回執(zhí)
那我們要怎么來(lái)實(shí)現(xiàn)回執(zhí)的發(fā)送呢?
我們定義一種回執(zhí)數(shù)據(jù)格式ACK,MsgType有三種,分別是sent(已發(fā)送),delivered(已送達(dá)), read(已讀)。
消息格式如下:
message AckMsg {
id;
//消息id
fromId;
//發(fā)送者id
destId;
//接收者id
msgType;
//消息類型
ackMsgId;
//確認(rèn)的消息id
}
enum MsgType {
DELIVERED;
READ;
}
當(dāng)服務(wù)端接受到Alice發(fā)來(lái)的消息時(shí):
1)向Alice發(fā)送一個(gè)sent(hello)表示消息已經(jīng)被發(fā)送到服務(wù)器:
message AckMsg {
id= 2;
fromId = Alice;
destId = Bob;
msgType = SENT;
ackMsgId = 1;
}
2)服務(wù)器把hello轉(zhuǎn)發(fā)給Bob后,立刻向Alice發(fā)送delivered(hello)表示消息已經(jīng)發(fā)送給Bob:
message AckMsg {
id= 3;
fromId = Bob;
destId = Alice;
msgType = DELIVERED;
ackMsgId = 1;
}
3)Bob閱讀消息后,客戶端向服務(wù)器發(fā)送read(hello)表示消息已讀:
message AckMsg {
id= 4;
fromId = Bob;
destId = Alice;
msgType = READ;
ackMsgId = 1;
}
這個(gè)消息會(huì)像一個(gè)普通聊天消息一樣被服務(wù)器處理,最終發(fā)送給Alice。
在服務(wù)器這里不區(qū)分ChatMsg和AckMsg,處理過(guò)程都是一樣的:解析消息的destId并進(jìn)行轉(zhuǎn)發(fā)。
4、水平擴(kuò)展
當(dāng)用戶量越來(lái)越大,必然需要增加服務(wù)器的數(shù)量,用戶的連接被分散在不同的機(jī)器上。此時(shí),就需要存儲(chǔ)用戶連接在哪臺(tái)機(jī)器上。
我們引入一個(gè)新的模塊來(lái)管理用戶的連接信息。
4.1 管理用戶狀態(tài)
模塊叫做user status,共有三個(gè)接口:
public interface UserStatusService {
/**
* 用戶上線,存儲(chǔ)userId與機(jī)器id的關(guān)系
*
* @param userId
* @param connectorId
* @return 如果當(dāng)前用戶在線,則返回他連接的機(jī)器id,否則返回null
*/
String online(String userId, String connectorId);
/**
* 用戶下線
*
* @param userId
*/
voidoffline(String userId);
/**
* 通過(guò)用戶id查找他當(dāng)前連接的機(jī)器id
*
* @param userId
* @return
*/
String getConnectorId(String userId);
}
這樣我們就能夠?qū)τ脩暨B接狀態(tài)進(jìn)行管理了,具體的實(shí)現(xiàn)應(yīng)考慮服務(wù)的用戶量、期望性能等進(jìn)行實(shí)現(xiàn)。
此處我們使用redis來(lái)實(shí)現(xiàn),將userId和connectorId的關(guān)系以key-value的形式存儲(chǔ)。
4.2 消息轉(zhuǎn)發(fā)
除此之外,還需要一個(gè)模塊在不同的機(jī)器上轉(zhuǎn)發(fā)消息,如下結(jié)構(gòu):
此時(shí)我們的服務(wù)被拆分成了connector和transfer兩個(gè)模塊,connector模塊用于維持用戶的長(zhǎng)鏈接,而transfer的作用是將消息在多個(gè)connector之間轉(zhuǎn)發(fā)。
現(xiàn)在Alice和Bob連接到了兩臺(tái)connector上,那么消息要如何傳遞呢?
1)Alice上線,連接到機(jī)器[1]上時(shí):
1.1)將Alice和它的連接存入內(nèi)存中。
1.2)調(diào)用user status的online方法記錄Alice上線。
2)Alice發(fā)送了一條消息給Bob:
2.1)機(jī)器[1]收到消息后,解析destId,在內(nèi)存中查找是否有Bob。
2.2)如果沒(méi)有,代表Bob未連接到這臺(tái)機(jī)器,則轉(zhuǎn)發(fā)給transfer。
3)transfer調(diào)用user status的getConnectorId(Bob)方法找到Bob所連接的connector,返回機(jī)器[2],則轉(zhuǎn)發(fā)給機(jī)器[2]。
流程圖:
4.3 總結(jié)
引入user status模塊管理用戶連接,transfer模塊在不同的機(jī)器之間轉(zhuǎn)發(fā),使服務(wù)可以水平擴(kuò)展。為了滿足實(shí)時(shí)轉(zhuǎn)發(fā),transfer需要和每臺(tái)connector機(jī)器都保持長(zhǎng)鏈接。
5、離線消息
如果用戶當(dāng)前不在線,就必須把消息持久化下來(lái),等待用戶下次上線再推送,這里使用mysql存儲(chǔ)離線消息。
為了方便地水平擴(kuò)展,我們使用消息隊(duì)列進(jìn)行解耦:
1)transfer接收到消息后如果發(fā)現(xiàn)用戶不在線,就發(fā)送給消息隊(duì)列入庫(kù);
2)用戶登錄時(shí),服務(wù)器從庫(kù)里拉取離線消息進(jìn)行推送。
6、用戶登錄、好友關(guān)系
用戶的注冊(cè)登錄、賬戶管理、好友關(guān)系鏈等功能更適合使用http協(xié)議,因此我們將這個(gè)模塊做成一個(gè)restful服務(wù),對(duì)外暴露http接口供客戶端調(diào)用。
至此服務(wù)端的基本架構(gòu)就完成了:
7、中場(chǎng)休息 ... ...
本文以上內(nèi)容,本篇幫大家構(gòu)建了IM服務(wù)端的架構(gòu),但還有很多細(xì)節(jié)需要我們?nèi)ニ伎肌?/p>
例如:
1)如何保證消息的順序和唯一
2)多個(gè)設(shè)備在線如何保證消息一致性
3)如何處理消息發(fā)送失敗
4)消息的安全性
5)如果要存儲(chǔ)聊天記錄要怎么做
6)數(shù)據(jù)庫(kù)分表分庫(kù)
7)服務(wù)高可用
……
更多細(xì)節(jié)實(shí)現(xiàn)請(qǐng)繼續(xù)讀下半部分啦~
8、可靠性
什么是可靠性?對(duì)于一個(gè)IM系統(tǒng)來(lái)說(shuō),可靠的定義至少是不丟消息、消息不重復(fù)、不亂序,滿足這三點(diǎn),才能說(shuō)有一個(gè)好的聊天體驗(yàn)。
8.1 不丟消息
我們先從不丟消息開(kāi)始講起。
首先復(fù)習(xí)一下上面章節(jié)中設(shè)計(jì)的服務(wù)端架構(gòu):
我們先從一個(gè)簡(jiǎn)單例子開(kāi)始思考:當(dāng)Alice給Bob發(fā)送一條消息時(shí),可能要經(jīng)過(guò)這樣一條鏈路:
1)client-->connecter
2)connector-->transfer
3)transfer-->connector
4)connector-->client
在這整個(gè)鏈路中的每個(gè)環(huán)節(jié)都有可能出問(wèn)題,雖然tcp協(xié)議是可靠的,但是它只能保證鏈路層的可靠,無(wú)法保證應(yīng)用層的可靠。
例如在第一步中,connector收到了從client發(fā)出的消息,但是轉(zhuǎn)發(fā)給transfer失敗,那么這條消息Bob就無(wú)法收到,而Alice也不會(huì)意識(shí)到消息發(fā)送失敗了。
如果Bob狀態(tài)是離線,那么消息鏈路就是:
1)client-->connector
2)connector-->transfer
3)transfer-->mq
如果在第三步中,transfer收到了來(lái)自connector的消息,但是離線消息入庫(kù)失敗,那么這個(gè)消息也是傳遞失敗了。
為了保證應(yīng)用層的可靠,我們必須要有一個(gè)ack機(jī)制,使發(fā)送方能夠確認(rèn)對(duì)方收到了這條消息。
具體的實(shí)現(xiàn),我們模仿tcp協(xié)議做一個(gè)應(yīng)用層的ack機(jī)制。
tcp的報(bào)文是以字節(jié)(byte)為單位的,而我們以message單位。
發(fā)送方每次發(fā)送一個(gè)消息,就要等待對(duì)方的ack回應(yīng),在ack確認(rèn)消息中應(yīng)該帶有收到的id以便發(fā)送方識(shí)別。
其次,發(fā)送方需要維護(hù)一個(gè)等待ack的隊(duì)列。 每次發(fā)送一個(gè)消息之后,就將消息和一個(gè)計(jì)時(shí)器入隊(duì)。
另外存在一個(gè)線程一直輪詢隊(duì)列,如果有超時(shí)未收到ack的,就取出消息重發(fā)。
超時(shí)未收到ack的消息有兩種處理方式:
1)和tcp一樣不斷發(fā)送直到收到ack為止。
2)設(shè)定一個(gè)最大重試次數(shù),超過(guò)這個(gè)次數(shù)還沒(méi)收到ack,就使用失敗機(jī)制處理,節(jié)約資源。例如如果是connector長(zhǎng)時(shí)間未收到client的ack,那么可以主動(dòng)斷開(kāi)和客戶端的連接,剩下未發(fā)送的消息就作為離線消息入庫(kù),客戶端斷連后嘗試重連服務(wù)器即可。
8.2 不重復(fù)、不亂序
有的時(shí)候因?yàn)榫W(wǎng)絡(luò)原因可能導(dǎo)致ack收到較慢,發(fā)送方就會(huì)重復(fù)發(fā)送,那么接收方必須有一個(gè)去重機(jī)制。
去重的方式是給每個(gè)消息增加一個(gè)唯一id。這個(gè)唯一id并不一定是全局的,只需要在一個(gè)會(huì)話中唯一即可。例如某兩個(gè)人的會(huì)話,或者某一個(gè)群。如果網(wǎng)絡(luò)斷連了,重新連接后,就是新的會(huì)話了,id會(huì)重新從0開(kāi)始。
關(guān)于消息ID的生成算法方面的文章,請(qǐng)?jiān)敿?xì)參考:
《融云技術(shù)分享:解密融云IM產(chǎn)品的聊天消息ID生成策略》
《微信技術(shù)分享:微信的海量IM聊天消息序列號(hào)生成實(shí)踐(算法原理篇)》
接收方需要在當(dāng)前會(huì)話中維護(hù)收到的最后一個(gè)消息的id,叫做lastId。
每次收到一個(gè)新消息, 就將id與lastId作比較看是否連續(xù),如果不連續(xù),就放入一個(gè)暫存隊(duì)列 queue中稍后處理。
例如:
1)當(dāng)前會(huì)話的lastId=1,接著服務(wù)器收到了消息msg(id=2),可以判斷收到的消息是連續(xù)的,就處理消息,將lastId修改為2;
2)但是如果服務(wù)器收到消息msg(id=3),就說(shuō)明消息亂序到達(dá)了,那么就將這個(gè)消息入隊(duì),等待lastId變?yōu)?后,(即服務(wù)器收到消息msg(id=2)并處理完了),再取出這個(gè)消息處理。
因此,判斷消息是否重復(fù)只需要判斷msgId>lastId && !queue.contains(msgId)即可。如果收到重復(fù)的消息,可以判斷是ack未送達(dá),就再發(fā)送一次ack。
接收方收到消息后完整的處理流程如下:
偽代碼如下:
class ProcessMsgNode{
/**
* 接收到的消息
*/
privateMessage message;
/**
* 處理消息的方法
*/
privateConsumer<Message> consumer;
}
public CompletableFuture<Void> offer(Long id,Message message,Consumer<Message> consumer) {
if(isRepeat(id)) {
//消息重復(fù)
sendAck(id);
return null;
}
if(!isConsist(id)) {
//消息不連續(xù)
notConsistMsgMap.put(id, newProcessMsgNode(message, consumer));
return null;
}
//處理消息
returnprocess(id, message, consumer);
}
private CompletableFuture<Void> process(Long id, Message message, Consumer<Message> consumer) {
return CompletableFuture
.runAsync(() -> consumer.accept(message))
.thenAccept(v -> sendAck(id))
.thenAccept(v -> lastId.set(id))
.thenComposeAsync(v -> {
Long nextId = nextId(id);
if(notConsistMsgMap.containsKey(nextId)) {
//隊(duì)列中有下個(gè)消息
ProcessMsgNode node = notConsistMsgMap.get(nextId);
returnprocess(nextId, node.getMessage(), consumer);
} else{
//隊(duì)列中沒(méi)有下個(gè)消息
CompletableFuture<Void> future = newCompletableFuture<>();
future.complete(null);
returnfuture;
}
})
.exceptionally(e -> {
logger.error("[process received msg] has error", e);
returnnull;
});
}
9、安全性
無(wú)論是聊天記錄還是離線消息,肯定都會(huì)在服務(wù)端存儲(chǔ)備份,那么消息的安全性,保護(hù)客戶的隱私也至關(guān)重要。
因此所有的消息都必須要加密處理。
在存儲(chǔ)模塊里,維護(hù)用戶信息和關(guān)系鏈有兩張基礎(chǔ)表,分別是im_user用戶表和im_relation關(guān)系鏈表。
im_user表用于存放用戶常規(guī)信息,例如用戶名密碼等,結(jié)構(gòu)比較簡(jiǎn)單。
im_relation表用于記錄好友關(guān)系。
結(jié)構(gòu)如下:
CREATE TABLE `im_relation` (
`id` bigint(20) COMMENT '關(guān)系id',
`user_id1` varchar(100) COMMENT '用戶1id',
`user_id2` varchar(100) COMMENT '用戶2id',
`encrypt_key` char(33) COMMENT 'aes密鑰',
`gmt_create` timestamp DEFAULT CURRENT_TIMESTAMP,
`gmt_update` timestamp DEFAUL TCURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARYKEY(`id`),
UNIQUE KEY `USERID1_USERID2` (`user_id1`,`user_id2`)
);
1)user_id1和user_id2是互為好友的用戶id,為了避免重復(fù),存儲(chǔ)時(shí)按照user_id1<user_id2的順序存,并且加上聯(lián)合索引;
2)encrypt_key是隨機(jī)生成的密鑰。當(dāng)客戶端登錄時(shí),就會(huì)從數(shù)據(jù)庫(kù)中獲取該用戶的所有的relation,存在內(nèi)存中,以便后續(xù)加密解密;
3)當(dāng)客戶端給某個(gè)好友發(fā)送消息時(shí),取出內(nèi)存中該關(guān)系的密鑰,加密后發(fā)送。同樣,當(dāng)收到一條消息時(shí),取出相應(yīng)的密鑰解密。
客戶端完整登錄流程如下:
1)client調(diào)用rest接口登錄;
2)client調(diào)用rest接口獲取該用戶所有relation;
3)client向connector發(fā)送greet消息,通知上線;
4)connector拉取離線消息推送給client;
5)connector更新用戶session。
那為什么connector要先推送離線消息再更新session呢?
我們思考一下如果順序倒過(guò)來(lái)會(huì)發(fā)生什么:
1)用戶Alice登錄服務(wù)器;
2)connector更新session;
3)推送離線消息;
4)此時(shí)Bob發(fā)送了一條消息給Alice。
如果離線消息還在推送的過(guò)程中,Bob發(fā)送了新消息給Alice,服務(wù)器獲取到Alice的session,就會(huì)立刻推送。這時(shí)新消息就有可能夾在一堆離線消息當(dāng)中推過(guò)去了,那這時(shí),Alice收到的消息就亂序了。
而我們必須保證離線消息的順序在新消息之前。
那么如果先推送離線消息,之后才更新session。在離線消息推送的過(guò)程中,Alice的狀態(tài)就是“未上線”,這時(shí)Bob新發(fā)送的消息只會(huì)入庫(kù)im_offline,im_offline表中的數(shù)據(jù)被讀完之后才會(huì)“上線”開(kāi)始接受新消息。這也就避免了亂序。
10、存儲(chǔ)設(shè)計(jì)
10.1 存儲(chǔ)離線消息
當(dāng)用戶不在線時(shí),離線消息必然要存儲(chǔ)在服務(wù)端,等待用戶上線再推送。理解了上一個(gè)小節(jié)后,離線消息的存儲(chǔ)就非常容易了。
增加一張離線消息表im_offline,表結(jié)構(gòu)如下:
CREATE TABLE `im_offline` (
`id` int(11) COMMENT '主鍵',
`msg_id` bigint(20) COMMENT '消息id',
`msg_type` int(2) COMMENT '消息類型',
`content` varbinary(5000) COMMENT '消息內(nèi)容',
`to_user_id` varchar(100) COMMENT '收件人id',
`has_read` tinyint(1) COMMENT '是否閱讀',
`gmt_create` timestamp COMMENT '創(chuàng)建時(shí)間',
PRIMARY KEY(`id`)
);
msg_type用于區(qū)分消息類型(chat,ack),content加密后的消息內(nèi)容以byte數(shù)組的形式存儲(chǔ)。
用戶上線時(shí)按照條件to_user_id=用戶id拉取記錄即可。
10.2 防止離線消息重復(fù)推送
我們思考一下多端登錄的情況,Alice有兩臺(tái)設(shè)備同時(shí)登陸,在這種并發(fā)的情況下,我們就需要某種機(jī)制來(lái)保證離線消息只被讀取一次。
這里利用CAS機(jī)制來(lái)實(shí)現(xiàn):
1)首先取出所有has_read=false的字段;
2)檢查每條消息的has_read值是否為false,如果是,則改為true。這是原子操作:
1updateim_offline sethas_read = truewhereid = ${msg_id} andhas_read = false
3)修改成功則推送,失敗則不推送。
相信到這里,同學(xué)們已經(jīng)可以自己動(dòng)手搭建一個(gè)完整可用的IM服務(wù)端了。
11、完整源碼下載
從零開(kāi)發(fā)一個(gè)IM服務(wù)端(完整源碼)(52im.net).zip (或自行從github下載:https://github.com/52im/IM)
附錄:更多IM開(kāi)發(fā)文章
[1] 更多IM代碼實(shí)踐(適合新手):
《自已開(kāi)發(fā)IM有那么難嗎?手把手教你自擼一個(gè)Andriod版簡(jiǎn)易IM (有源碼)》
《一種Android端IM智能心跳算法的設(shè)計(jì)與實(shí)現(xiàn)探討(含樣例代碼)》
《手把手教你用Netty實(shí)現(xiàn)網(wǎng)絡(luò)通信程序的心跳機(jī)制、斷線重連機(jī)制》
《詳解Netty的安全性:原理介紹、代碼演示(上篇)》
《詳解Netty的安全性:原理介紹、代碼演示(下篇)》
《微信本地?cái)?shù)據(jù)庫(kù)破解版(含iOS、Android),僅供學(xué)習(xí)研究 [附件下載]》
《Java NIO基礎(chǔ)視頻教程、MINA視頻教程、Netty快速入門視頻 [有源碼]》
《輕量級(jí)即時(shí)通訊框架MobileIMSDK的iOS源碼(開(kāi)源版)[附件下載]》
《開(kāi)源IM工程“蘑菇街TeamTalk”2015年5月前未刪減版完整代碼 [附件下載]》
《微信本地?cái)?shù)據(jù)庫(kù)破解版(含iOS、Android),僅供學(xué)習(xí)研究 [附件下載]》
《NIO框架入門(一):服務(wù)端基于Netty4的UDP雙向通信Demo演示 [附件下載]》
《NIO框架入門(二):服務(wù)端基于MINA2的UDP雙向通信Demo演示 [附件下載]》
《NIO框架入門(三):iOS與MINA2、Netty4的跨平臺(tái)UDP雙向通信實(shí)戰(zhàn) [附件下載]》
《NIO框架入門(四):Android與MINA2、Netty4的跨平臺(tái)UDP雙向通信實(shí)戰(zhàn) [附件下載]》
《用于IM中圖片壓縮的Android工具類源碼,效果可媲美微信 [附件下載]》
《高仿Android版手機(jī)QQ可拖拽未讀數(shù)小氣泡源碼 [附件下載]》
《一個(gè)WebSocket實(shí)時(shí)聊天室Demo:基于node.js+socket.io [附件下載]》
《Android聊天界面源碼:實(shí)現(xiàn)了聊天氣泡、表情圖標(biāo)(可翻頁(yè)) [附件下載]》
《高仿Android版手機(jī)QQ首頁(yè)側(cè)滑菜單源碼 [附件下載]》
《開(kāi)源libco庫(kù):?jiǎn)螜C(jī)千萬(wàn)連接、支撐微信8億用戶的后臺(tái)框架基石 [源碼下載]》
《分享java AMR音頻文件合并源碼,全網(wǎng)最全》
《微信團(tuán)隊(duì)原創(chuàng)Android資源混淆工具:AndResGuard [有源碼]》
《一個(gè)基于MQTT通信協(xié)議的完整Android推送Demo [附件下載]》
《Android版高仿微信聊天界面源碼 [附件下載]》
《高仿手機(jī)QQ的Android版鎖屏聊天消息提醒功能 [附件下載]》
《高仿iOS版手機(jī)QQ錄音及振幅動(dòng)畫(huà)完整實(shí)現(xiàn) [源碼下載]》
《Android端社交應(yīng)用中的評(píng)論和回復(fù)功能實(shí)戰(zhàn)分享[圖文+源碼]》
《Android端IM應(yīng)用中的@人功能實(shí)現(xiàn):仿微博、QQ、微信,零入侵、高可擴(kuò)展[圖文+源碼]》
《仿微信的IM聊天時(shí)間顯示格式(含iOS/Android/Web實(shí)現(xiàn))[圖文+源碼]》
《Android版仿微信朋友圈圖片拖拽返回效果 [源碼下載]》
《適合新手:從零開(kāi)發(fā)一個(gè)IM服務(wù)端(基于Netty,有完整源碼)》
>> 更多同類文章 ……
[2] IM群聊相關(guān)的技術(shù)文章:
《快速裂變:見(jiàn)證微信強(qiáng)大后臺(tái)架構(gòu)從0到1的演進(jìn)歷程(一)》
《如何保證IM實(shí)時(shí)消息的“時(shí)序性”與“一致性”?》
《IM單聊和群聊中的在線狀態(tài)同步應(yīng)該用“推”還是“拉”?》
《IM群聊消息如此復(fù)雜,如何保證不丟不重?》
《微信后臺(tái)團(tuán)隊(duì):微信后臺(tái)異步消息隊(duì)列的優(yōu)化升級(jí)實(shí)踐分享》
《移動(dòng)端IM中大規(guī)模群消息的推送如何保證效率、實(shí)時(shí)性?》
《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲(chǔ)方案探討》
《關(guān)于IM即時(shí)通訊群聊消息的亂序問(wèn)題討論》
《IM群聊消息的已讀回執(zhí)功能該怎么實(shí)現(xiàn)?》
《IM群聊消息究竟是存1份(即擴(kuò)散讀)還是存多份(即擴(kuò)散寫)?》
《一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計(jì)實(shí)踐》
《[技術(shù)腦洞] 如果把14億中國(guó)人拉到一個(gè)微信群里技術(shù)上能實(shí)現(xiàn)嗎?》
《IM群聊機(jī)制,除了循環(huán)去發(fā)消息還有什么方式?如何優(yōu)化?》
《網(wǎng)易云信技術(shù)分享:IM中的萬(wàn)人群聊技術(shù)方案實(shí)踐總結(jié)》
>> 更多同類文章 ……
[3] 有關(guān)IM架構(gòu)設(shè)計(jì)的文章:
《淺談IM系統(tǒng)的架構(gòu)設(shè)計(jì)》
《簡(jiǎn)述移動(dòng)端IM開(kāi)發(fā)的那些坑:架構(gòu)設(shè)計(jì)、通信協(xié)議和客戶端》
《一套海量在線用戶的移動(dòng)端IM架構(gòu)設(shè)計(jì)實(shí)踐分享(含詳細(xì)圖文)》
《一套原創(chuàng)分布式即時(shí)通訊(IM)系統(tǒng)理論架構(gòu)方案》
《從零到卓越:京東客服即時(shí)通訊系統(tǒng)的技術(shù)架構(gòu)演進(jìn)歷程》
《蘑菇街即時(shí)通訊/IM服務(wù)器開(kāi)發(fā)之架構(gòu)選擇》
《騰訊QQ1.4億在線用戶的技術(shù)挑戰(zhàn)和架構(gòu)演進(jìn)之路PPT》
《微信后臺(tái)基于時(shí)間序的海量數(shù)據(jù)冷熱分級(jí)架構(gòu)設(shè)計(jì)實(shí)踐》
《微信技術(shù)總監(jiān)談架構(gòu):微信之道——大道至簡(jiǎn)(演講全文)》
《如何解讀《微信技術(shù)總監(jiān)談架構(gòu):微信之道——大道至簡(jiǎn)》》
《快速裂變:見(jiàn)證微信強(qiáng)大后臺(tái)架構(gòu)從0到1的演進(jìn)歷程(一)》
《17年的實(shí)踐:騰訊海量產(chǎn)品的技術(shù)方法論》
《移動(dòng)端IM中大規(guī)模群消息的推送如何保證效率、實(shí)時(shí)性?》
《現(xiàn)代IM系統(tǒng)中聊天消息的同步和存儲(chǔ)方案探討》
《IM開(kāi)發(fā)基礎(chǔ)知識(shí)補(bǔ)課(二):如何設(shè)計(jì)大量圖片文件的服務(wù)端存儲(chǔ)架構(gòu)?》
《IM開(kāi)發(fā)基礎(chǔ)知識(shí)補(bǔ)課(三):快速理解服務(wù)端數(shù)據(jù)庫(kù)讀寫分離原理及實(shí)踐建議》
《IM開(kāi)發(fā)基礎(chǔ)知識(shí)補(bǔ)課(四):正確理解HTTP短連接中的Cookie、Session和Token》
《WhatsApp技術(shù)實(shí)踐分享:32人工程團(tuán)隊(duì)創(chuàng)造的技術(shù)神話》
《微信朋友圈千億訪問(wèn)量背后的技術(shù)挑戰(zhàn)和實(shí)踐總結(jié)》
《王者榮耀2億用戶量的背后:產(chǎn)品定位、技術(shù)架構(gòu)、網(wǎng)絡(luò)方案等》
《IM系統(tǒng)的MQ消息中間件選型:Kafka還是RabbitMQ?》
《騰訊資深架構(gòu)師干貨總結(jié):一文讀懂大型分布式系統(tǒng)設(shè)計(jì)的方方面面》
《以微博類應(yīng)用場(chǎng)景為例,總結(jié)海量社交系統(tǒng)的架構(gòu)設(shè)計(jì)步驟》
《快速理解高性能HTTP服務(wù)端的負(fù)載均衡技術(shù)原理》
《子彈短信光鮮的背后:網(wǎng)易云信首席架構(gòu)師分享億級(jí)IM平臺(tái)的技術(shù)實(shí)踐》
《知乎技術(shù)分享:從單機(jī)到2000萬(wàn)QPS并發(fā)的Redis高性能緩存實(shí)踐之路》
《IM開(kāi)發(fā)基礎(chǔ)知識(shí)補(bǔ)課(五):通俗易懂,正確理解并用好MQ消息隊(duì)列》
《微信技術(shù)分享:微信的海量IM聊天消息序列號(hào)生成實(shí)踐(算法原理篇)》
《微信技術(shù)分享:微信的海量IM聊天消息序列號(hào)生成實(shí)踐(容災(zāi)方案篇)》
《新手入門:零基礎(chǔ)理解大型分布式架構(gòu)的演進(jìn)歷史、技術(shù)原理、最佳實(shí)踐》
《一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計(jì)實(shí)踐》
《阿里技術(shù)分享:深度揭秘阿里數(shù)據(jù)庫(kù)技術(shù)方案的10年變遷史》
《阿里技術(shù)分享:阿里自研金融級(jí)數(shù)據(jù)庫(kù)OceanBase的艱辛成長(zhǎng)之路》
《社交軟件紅包技術(shù)解密(一):全面解密QQ紅包技術(shù)方案——架構(gòu)、技術(shù)實(shí)現(xiàn)等》
《社交軟件紅包技術(shù)解密(二):解密微信搖一搖紅包從0到1的技術(shù)演進(jìn)》
《社交軟件紅包技術(shù)解密(三):微信搖一搖紅包雨背后的技術(shù)細(xì)節(jié)》
《社交軟件紅包技術(shù)解密(四):微信紅包系統(tǒng)是如何應(yīng)對(duì)高并發(fā)的》
《社交軟件紅包技術(shù)解密(五):微信紅包系統(tǒng)是如何實(shí)現(xiàn)高可用性的》
《社交軟件紅包技術(shù)解密(六):微信紅包系統(tǒng)的存儲(chǔ)層架構(gòu)演進(jìn)實(shí)踐》
《社交軟件紅包技術(shù)解密(七):支付寶紅包的海量高并發(fā)技術(shù)實(shí)踐》
《社交軟件紅包技術(shù)解密(八):全面解密微博紅包技術(shù)方案》
《社交軟件紅包技術(shù)解密(九):談?wù)勈諵紅包的功能邏輯、容災(zāi)、運(yùn)維、架構(gòu)等》
《即時(shí)通訊新手入門:一文讀懂什么是Nginx?它能否實(shí)現(xiàn)IM的負(fù)載均衡?》
《即時(shí)通訊新手入門:快速理解RPC技術(shù)——基本概念、原理和用途》
《多維度對(duì)比5款主流分布式MQ消息隊(duì)列,媽媽再也不擔(dān)心我的技術(shù)選型了》
《從游擊隊(duì)到正規(guī)軍:馬蜂窩旅游網(wǎng)的IM系統(tǒng)架構(gòu)演進(jìn)之路》
《IM開(kāi)發(fā)基礎(chǔ)知識(shí)補(bǔ)課(六):數(shù)據(jù)庫(kù)用NoSQL還是SQL?讀這篇就夠了!》
>> 更多同類文章 ……
(本文同步發(fā)布于:http://www.52im.net/thread-2768-1-1.html)
作者:Jack Jiang (點(diǎn)擊作者姓名進(jìn)入Github)
出處:http://www.52im.net/space-uid-1.html
交流:歡迎加入即時(shí)通訊開(kāi)發(fā)交流群 215891622
討論:http://www.52im.net/
Jack Jiang同時(shí)是【原創(chuàng)Java
Swing外觀工程BeautyEye】和【輕量級(jí)移動(dòng)端即時(shí)通訊框架MobileIMSDK】的作者,可前往下載交流。
本博文
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處(也可前往 我的52im.net 找到我)。