最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

跟著源碼學(xué)IM(九):基于Netty實現(xiàn)一套分布式IM系統(tǒng)

2021-12-20 21:28 作者:nickkckckck  | 我要投稿

本文作者小傅哥,原題“使用DDD+Netty,開發(fā)一個分布式IM(即時通信)系統(tǒng)”。為了提升閱讀體驗,有大量修訂和改動,感謝原作者。

1、本文引言

計算機(jī)編程的學(xué)習(xí),能不能把知識學(xué)到手,講究的是動手實踐。在我編寫的文章中,基本都是以實踐代碼驗證結(jié)果為核心來講述文章內(nèi)容。

從小我就喜歡動手,就以一個即時通信的項目為例,已經(jīng)基于不同技術(shù)方案實現(xiàn)了5、6次,僅僅為了實踐技術(shù),截圖如下。

正如上圖這樣:

  • 1)有些是剛學(xué)完Socket和Swing的時候,想動手試試這些技術(shù)能不能寫個QQ出來;

  • 2)也有的是因為實習(xí)培訓(xùn)需要完成的項目,不過在有了一些基礎(chǔ)后,一周時間就能寫完全部功能;

  • 3)雖然這些項目在現(xiàn)在看上去還是丑丑的界面,以及代碼邏輯可能也不是那么完善。但放在學(xué)習(xí)階段的每一次實現(xiàn)中,都能為自己帶來很多技術(shù)上的成長。

那么,這次借本文的機(jī)會,將IM實踐的機(jī)會留給你,希望你能用的上。

接下來的內(nèi)容,我會為你介紹如何開發(fā)一個IM的方方面面,包括系統(tǒng)架構(gòu)、通信協(xié)議、單聊群聊、表情發(fā)送、UI事件驅(qū)動等,以及全套的實踐源碼讓你可以上手學(xué)習(xí)。

注:源碼在本文“4、本文源碼”一節(jié)的附件處可下載。

學(xué)習(xí)交流:

- 移動端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動端IM》

- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK?

(本文已同步發(fā)布于:http://www.52im.net/thread-3789-1-1.html)

2、知識準(zhǔn)備

* 重要提示:本文不是一篇即時通訊理論文章,文章內(nèi)容全部由實戰(zhàn)代碼組織而成,如果你對即時通訊(IM)技術(shù)理論了解的太少,建議先詳細(xì)閱讀:《新手入門一篇就夠:從零開發(fā)移動端IM》。

可能有人不知道 Netty 是什么,這里簡單介紹下:

Netty 是一個 Java 開源框架。Netty 提供異步的、事件驅(qū)動的網(wǎng)絡(luò)應(yīng)用程序框架和工具,用以快速開發(fā)高性能、高可靠性的網(wǎng)絡(luò)服務(wù)器和客戶端程序。

也就是說,Netty 是一個基于 NIO 的客戶、服務(wù)器端編程框架,使用Netty 可以確保你快速和簡單的開發(fā)出一個網(wǎng)絡(luò)應(yīng)用,例如實現(xiàn)了某種協(xié)議的客戶,服務(wù)端應(yīng)用。

Netty 相當(dāng)簡化和流線化了網(wǎng)絡(luò)應(yīng)用的編程開發(fā)過程,例如,TCP 和 UDP 的 Socket 服務(wù)開發(fā)。

以下是幾篇有關(guān)Netty的入門文章,值得一讀:

  1. 《新手入門:目前為止最透徹的的Netty高性能原理和框架架構(gòu)解析》

  2. 《寫給初學(xué)者:Java高性能NIO框架Netty的學(xué)習(xí)方法和進(jìn)階策略》

  3. 《史上最通俗Netty框架入門長文:基本介紹、環(huán)境搭建、動手實戰(zhàn)》

如果你連Java的NIO都不知道是什么,下面的文章建議優(yōu)先讀一下:

  1. 《少啰嗦!一分鐘帶你讀懂Java的NIO和經(jīng)典IO的區(qū)別》

  2. 《史上最強(qiáng)Java NIO入門:擔(dān)心從入門到放棄的,請讀這篇!》

  3. 《Java的BIO和NIO很難懂?用代碼實踐給你看,再不懂我轉(zhuǎn)行!》

Netty源碼和API的在線閱讀地址:

  • 1)Netty-4.1.x 完整源碼(在線閱讀版)(* 推薦)

  • 2)Netty-4.0.x 完整源碼(在線閱讀版)

  • 3)Netty-4.1.x API文檔(在線版)(* 推薦)

  • 4)Netty-4.0.x API文檔(在線版)

3、運行效果

在開始學(xué)習(xí)之前,先給大家演示下本文配套源碼的運行效果(源碼在本文“4、本文源碼”一節(jié)的附件處可下載)。

聊天頁面:

添加好友:

消息提醒:

4、本文源碼

本文完整代碼附件下載:

(請從同步發(fā)布鏈接中下載:http://www.52im.net/thread-3789-1-1.html)

源碼的目錄結(jié)構(gòu),如下圖所示:

這套 IM 代碼分為了三組模塊:UI、客戶端、服務(wù)端。

之所以這樣拆分,是為了將UI展示與業(yè)務(wù)邏輯隔離,使用事件和接口進(jìn)行驅(qū)動,讓代碼層次更加干凈整潔易于擴(kuò)展和維護(hù)。

各模塊的作用,具體解釋如下:

5、系統(tǒng)設(shè)計

在這套IM中,服務(wù)端采用DDD領(lǐng)域驅(qū)動設(shè)計模式進(jìn)行搭建。將 Netty 的功能交給 SpringBoot 進(jìn)行啟??刂?,同時在服務(wù)端搭建控制臺可以非常方便的操作通信系統(tǒng),進(jìn)行用戶和通信管理。在客戶端的建設(shè)上采用UI分離的方式進(jìn)行搭建,以保證業(yè)務(wù)代碼與UI展示分離,做到非常易于擴(kuò)展的控制。

另外,在功能實現(xiàn)上包括:完美仿照微信桌面版客戶端、登錄、搜索添加好友、用戶通信、群組通信、表情發(fā)送等核心功能。如果有對于實際需要使用的功能,可以按照這套系統(tǒng)框架進(jìn)行擴(kuò)展。

?

解釋一下:

  • 1)UI開發(fā):使用JavaFx與Maven搭建UI桌面工程,逐步講解登錄框體、聊天框體、對話框、好友欄等各項UI展示及操作事件;

  • 2)架構(gòu)設(shè)計:使用DDD領(lǐng)域驅(qū)動設(shè)計的四層模型結(jié)構(gòu)與Netty結(jié)合使用,架構(gòu)出合理的分層框架(相應(yīng)庫表功能的設(shè)計);

  • 3)功能實現(xiàn):包括;登錄、添加好友、對話通知、消息發(fā)送、斷線重連等各項功能。

6、UI開發(fā)

6.1 功能劃分

聊天窗體,相對于登陸窗體來說,聊天窗體的內(nèi)容會比較多,同時也會相對復(fù)雜一些。

下圖是聊天窗體的功能定義草圖:

?

如上圖所示:

  • 1)首先是我們整個聊天主窗體的定義,是一塊空白面板,并去掉默認(rèn)的邊框按鈕 (最小化、退出等);

  • 2)之后是我們左側(cè)邊欄,我們稱之為條形 Bar,功能區(qū)域的實現(xiàn);

  • 3)最后添加窗體事件,當(dāng)點擊按鈕時變換 內(nèi)容面板 中的填充信息。

6.2 聊天界面

對話框選中后的內(nèi)容區(qū)域展現(xiàn),也就是用戶之間信息發(fā)送和展現(xiàn)。

從整體上看這是一個聯(lián)動的過程,點擊左側(cè)的對話框用戶,右側(cè)就有相應(yīng)內(nèi)容的填充。那么右側(cè)被填充對話列表 ListView 需要與每一個對話用戶關(guān)聯(lián),點擊聊天用戶的時候,是通過反復(fù)切換填充的過程。效果如下圖所示。

參見上圖,我解釋一下:

  • 1)點擊左側(cè)的每一個對話框體,右側(cè)聊天框填充內(nèi)容即隨之變化(同時還有相應(yīng)的對話名稱也會也變化);

  • 2)對話框中左側(cè)展示好友發(fā)送的信息,右側(cè)展示個人發(fā)送的信息(同時消息內(nèi)容會隨著內(nèi)容的增多而增加高度和寬度);

  • 3)最下面是文本輸入框,在后面的實現(xiàn)里我們文本輸入框采用公用的方式進(jìn)行設(shè)計,當(dāng)然你也可以設(shè)計為單獨的個人使用。

6.3 好友列表

大家都經(jīng)常使用 PC 端的微信,可以知道在好友欄里是分了幾段內(nèi)容的,其中包含:新的朋友、公眾號、群組和最下面的好友(功能劃分如下圖)。

參見上圖,我解釋一下:

  • 1)最上面的搜索框這部分內(nèi)容不變,和前面的一樣。我們目前使用的方式是 fxml 設(shè)計,例如這部分是通用功能,可以抽取出來放到代碼中,設(shè)計成一個組件元素類;

  • 2)經(jīng)過我們的分析,在使用 JavaFx 組件開發(fā)為基礎(chǔ)下,這部分是一種嵌套 ListView,也就是最底層的面板是一個 ListView,好友和群組有各是一個 ListView,這樣處理后我們會很方便的進(jìn)行數(shù)據(jù)填充;

  • 3)另外這樣的結(jié)構(gòu)主要有利于在我們程序運行過程中,如果你添加了好友,那么我們需要將好友信息刷新到好友欄中,而在數(shù)據(jù)填充的時候,為了更加便捷高效,所以我們設(shè)計了嵌套的 ListView(如果還不是特別理解,可以從后續(xù)的代碼中獲得答案)。

6.4 事件定義

在桌面版 UI 開發(fā)中,為了能使 UI 與業(yè)務(wù)邏輯隔離,需要在我們把 UI 打包后提供出操作界面的展示效果的接口以及界面操作事件抽象類。

那么可以按照下圖理解:

以上這些接口就是我們目前 UI 為外部提供的所有行為接口,這些接口的一個鏈路描述就是:打開窗口、搜索好友、添加好友、打開對話框、發(fā)送消息。

7、通信設(shè)計

7.1 系統(tǒng)架構(gòu)

在前面我說到更適合的架構(gòu),才是符合你當(dāng)下需要最好的架構(gòu)。

那么怎么設(shè)計需要的架構(gòu)呢?

之所以這樣設(shè)計,在這個系統(tǒng)里有如下幾點前提:

  • 1)系統(tǒng)在服務(wù)端要有 web 頁面進(jìn)行管理通信用戶以及服務(wù)端的控制和監(jiān)控;

  • 2)數(shù)據(jù)庫的對象類,不要被外部污染,要有隔離性(比如:你的數(shù)據(jù)庫類暴漏給外部做展示類使用了,那么現(xiàn)在需要增加一個字段,而這個字段又不是你數(shù)據(jù)庫存在的屬性。那么這個時候就已經(jīng)把數(shù)據(jù)庫類污染了)。

  • 3)因為目前都是在 Java 語言下實現(xiàn) Netty 通信,那么服務(wù)端與客戶端都會需要使用到通信過程中的協(xié)議定義和解析。那么我們需要抽離這一層對外提供 Jar 包(利于重用,不然客戶端和服務(wù)端復(fù)制同樣的代碼維護(hù),就太惡心了);

  • 4)接口、業(yè)務(wù)處理、底層服務(wù)、通信交互,要有明確的區(qū)分和實現(xiàn),避免造成混亂難以維護(hù)。

結(jié)合我們上面這四點的前提,你頭腦中有什么模型結(jié)構(gòu)體現(xiàn)了?以及相應(yīng)的技術(shù)棧選擇上是否有計劃了?

接下來我會介紹兩種架構(gòu)設(shè)計的模型,一種是你非常熟悉的 MVC,另外一種是你可能聽說過的 DDD 領(lǐng)域驅(qū)動設(shè)計。

7.2 通信協(xié)議

從圖稿上來看,我們在傳輸對象的時候需要在傳輸包中添加一個“幀標(biāo)識”以此來判斷當(dāng)前的業(yè)務(wù)對象是哪個對象,也就可以讓我們的業(yè)務(wù)更加清晰,避免使用大量的 if 語句判斷。

協(xié)議框架:

agreement

└── src

????├── main

????│?? ├── java

????│?? │?? └── org.itstack.naive.chat

????│?? │?????? ├── codec

????│?? │?????? │??? ├── ObjDecoder.java

????│?? │?????? │??? └── ObjEncoder.java

????│?? │?????? ├── protocol

????│?? │?????? │??? ├── demo

????│?? │?????? │??? ├── Command.java

????│?? │?????? │??? └── Packet.java

????│?? │?????? └── util

????│?? │???????????? └── SerializationUtil.java

????│?? ├── resources???

????│?? │?? └── Application.yml

????│?? └── webApp

????│?????? └── chat

????│?????? └── res

????│?????? └── index.html

????└── test

?????????└── java

?????????????└── org.itstack.demo.test

?????????????????└── ApiTest.java

協(xié)議包:

public abstract class Packet {

????private final static Map<Byte, Class<? extendsPacket>> packetType = new ConcurrentHashMap<>();

????static{

????????packetType.put(Command.LoginRequest, LoginRequest.class);

????????packetType.put(Command.LoginResponse, LoginResponse.class);

????????packetType.put(Command.MsgRequest, MsgRequest.class);

????????packetType.put(Command.MsgResponse, MsgResponse.class);

????????packetType.put(Command.TalkNoticeRequest, TalkNoticeRequest.class);

????????packetType.put(Command.TalkNoticeResponse, TalkNoticeResponse.class);

????????packetType.put(Command.SearchFriendRequest, SearchFriendRequest.class);

????????packetType.put(Command.SearchFriendResponse, SearchFriendResponse.class);

????????packetType.put(Command.AddFriendRequest, AddFriendRequest.class);

????????packetType.put(Command.AddFriendResponse, AddFriendResponse.class);

????????packetType.put(Command.DelTalkRequest, DelTalkRequest.class);

????????packetType.put(Command.MsgGroupRequest, MsgGroupRequest.class);

????????packetType.put(Command.MsgGroupResponse, MsgGroupResponse.class);

????????packetType.put(Command.ReconnectRequest, ReconnectRequest.class);

????}

????public static Class<? extends Packet> get(Byte command) {

????????return packetType.get(command);

????}

?

????/**

?????* 獲取協(xié)議指令

?????*

?????* @return 返回指令值

?????*/

????public abstract Byte getCommand();

}

7.3 添加好友

從上面的流程圖中可以看到,這里包含了兩部分內(nèi)容:搜索好友和添加好友。

當(dāng)添加完成好友后,好友會出現(xiàn)到我們的好友欄中。

并且這里面我們采用的是單方面同意加好友,也就是你添加一個好友的時候,對方也同樣有你的好友信息。

如果你的業(yè)務(wù)中是需要添加好友并同意的,那么可以在發(fā)起好友添加的時候,添加一條狀態(tài)信息,請求加好友。對方同意后,兩個用戶才能成為好友并進(jìn)行通信。

添加好友的樣例代碼:

public class AddFriendHandler extends MyBizHandler<AddFriendRequest> {

????public AddFriendHandler(UserService userService) {

????????super(userService);

????}

????@Override

????public void channelRead(Channel channel, AddFriendRequest msg) {

????????// 1. 添加好友到數(shù)據(jù)庫中[A->B B->A]

????????List<UserFriend> userFriendList = newArrayList<>();

????????userFriendList.add(newUserFriend(msg.getUserId(), msg.getFriendId()));

????????userFriendList.add(newUserFriend(msg.getFriendId(), msg.getUserId()));

????????userService.addUserFriend(userFriendList);

????????// 2. 推送好友添加完成 A

????????UserInfo userInfo = userService.queryUserInfo(msg.getFriendId());

????????channel.writeAndFlush(newAddFriendResponse(userInfo.getUserId(), userInfo.getUserNickName(), userInfo.getUserHead()));

????????// 3. 推送好友添加完成 B

????????Channel friendChannel = SocketChannelUtil.getChannel(msg.getFriendId());

????????if(null== friendChannel) return;

????????UserInfo friendInfo = userService.queryUserInfo(msg.getUserId());

????????friendChannel.writeAndFlush(newAddFriendResponse(friendInfo.getUserId(), friendInfo.getUserNickName(), friendInfo.getUserHead()));

????}

}

7.4 消息應(yīng)答

從整體的流程可以看到:在用戶發(fā)起好友、群組通信的時候,會觸發(fā)一個事件行為,接下來客戶端向服務(wù)端發(fā)送與好友的對話請求。

服務(wù)端收到對話請求后:如果是好友對話,那么需要保存與好友的通信信息到對話框中。同時通知好友,我與你要通信了。你在自己的對話框列表中,把我加進(jìn)去。

如果是群組通信:是可以不用這樣通知的,因為不可能把還沒有在線的所有群組用戶全部通知(人家還沒登錄呢),所以這部分只需要在用戶上線收到信息后,創(chuàng)建出對話框到列表中即可。可以仔細(xì)理解下,同時也可以想想其他實現(xiàn)的方式。

消息應(yīng)答樣例代碼:

public class MsgHandler extends MyBizHandler<MsgRequest> {

????public MsgHandler(UserService userService) {

????????super(userService);

????}

????@Override

????public void channelRead(Channel channel, MsgRequest msg) {

????????logger.info("消息信息處理:{}", JSON.toJSONString(msg));

????????// 異步寫庫

????????userService.asyncAppendChatRecord(newChatRecordInfo(msg.getUserId(), msg.getFriendId(), msg.getMsgText(), msg.getMsgType(), msg.getMsgDate()));

????????// 添加對話框[如果對方?jīng)]有你的對話框則添加]

????????userService.addTalkBoxInfo(msg.getFriendId(), msg.getUserId(), Constants.TalkType.Friend.getCode());

????????// 獲取好友通信管道

????????Channel friendChannel = SocketChannelUtil.getChannel(msg.getFriendId());

????????if(null== friendChannel) {

????????????logger.info("用戶id:{}未登錄!", msg.getFriendId());

????????????return;

????????}

????????// 發(fā)送消息

????????friendChannel.writeAndFlush(newMsgResponse(msg.getUserId(), msg.getMsgText(), msg.getMsgType(), msg.getMsgDate()));

????}

}

7.5 斷線重連

從上述流程中我們看到:當(dāng)網(wǎng)絡(luò)連接斷開以后,會像服務(wù)端發(fā)送重新鏈接的請求。 那么在這個發(fā)起鏈接的過程,和系統(tǒng)的最開始鏈接有所區(qū)別。斷線重連是需要將用戶的 ID 信息一同發(fā)送給服務(wù)端,好讓服務(wù)端可以去更新用戶與通信管道 Channel 的綁定關(guān)系。

同時還需要更新群組內(nèi)的重連信息,把用戶的重連加入群組映射中。此時就可以恢復(fù)用戶與好友和群組的通信功能。

消息應(yīng)答樣例代碼:

// Channel 狀態(tài)定時巡檢;3 秒后每 5 秒執(zhí)行一次

scheduledExecutorService.scheduleAtFixedRate(() -> {while(!nettyClient.isActive()) {System.out.println("通信管道巡檢:通信管道狀態(tài)"+ nettyClient.isActive());

????????try{System.out.println("通信管道巡檢:斷線重連 [Begin]");

????????????Channel freshChannel = executorService.submit(nettyClient).get();

????????????if(null== CacheUtil.userId) continue;

????????????freshChannel.writeAndFlush(newReconnectRequest(CacheUtil.userId));

????????} catch(InterruptedException | ExecutionException e) {System.out.println("通信管道巡檢:斷線重連 [Error]");}

????}

}, 3, 5, TimeUnit.SECONDS);

相關(guān)文章學(xué)習(xí):

  1. 《為何基于TCP協(xié)議的移動端IM仍然需要心跳?;顧C(jī)制?》

  2. 《一文讀懂即時通訊應(yīng)用中的網(wǎng)絡(luò)心跳包機(jī)制:作用、原理、實現(xiàn)思路等》

  3. 《融云技術(shù)分享:融云安卓端IM產(chǎn)品的網(wǎng)絡(luò)鏈路保活技術(shù)實踐》

  4. 《正確理解IM長連接的心跳及重連機(jī)制,并動手實現(xiàn)(有完整IM源碼)》

  5. 《一種Android端IM智能心跳算法的設(shè)計與實現(xiàn)探討(含樣例代碼)》

  6. 《手把手教你用Netty實現(xiàn)網(wǎng)絡(luò)通信程序的心跳機(jī)制、斷線重連機(jī)制》

  7. 《Web端即時通訊實踐干貨:如何讓你的WebSocket斷網(wǎng)重連更快速?》

7.6 集群通信

如上圖所示,我是這樣實現(xiàn)IM集群通信的:

  • 1)跨服務(wù)之間案例采用redis的發(fā)布和訂閱進(jìn)行傳遞消息,如果你是大型服務(wù)可以使用zookeeper;

  • 2)用戶A在發(fā)送消息給用戶B時候,需要傳遞B的channeId,以用于服務(wù)端進(jìn)行查找channeId所屬是否自己的服務(wù)內(nèi);

  • 3)單臺機(jī)器也可以啟動多個Netty服務(wù),程序內(nèi)會自動尋找可用端口。

8、本文小結(jié)

此IM系統(tǒng)涉及到的技術(shù)棧內(nèi)容較多:Netty4.x、SpringBoot、Mybatis、Mysql、JavaFx、layui等技術(shù)棧的使用,以及整個系統(tǒng)框架結(jié)構(gòu)采用DDD四層架構(gòu)+Socket模塊的方式進(jìn)行搭建,所有的UI都以前后端分離事件驅(qū)動方式進(jìn)行設(shè)計。在這個過程中只要你能堅持學(xué)習(xí)下來,那么一定會收獲非常多的內(nèi)容。足夠吹牛啦!

任何一個新技術(shù)棧的學(xué)習(xí)過程都會包括這樣一條路線:運行HelloWorld、熟練使用API、項目實踐以及最后的深度源碼挖掘。 那么在聽到這樣一個需求時候,Java程序員肯定會想到一些列的技術(shù)知識點來填充我們項目中的各個模塊(例如:界面用JavaFx、Swing等,通信用Socket或者知道Netty框架、服務(wù)端控制用MVC模型加上SpringBoot等)。但是怎么將這些各個技術(shù)棧合理的架設(shè)出我們的系統(tǒng)確是學(xué)習(xí)、實踐、成長過程中最重要的部分。

好了,IM開發(fā)實際上涉及的知識維度非常多,限于篇幅就不在這里啰嗦更多,各位讀者務(wù)必對著源碼同步進(jìn)行學(xué)習(xí),這樣效果會更好(源碼在本文“4、本文源碼”一節(jié)的附件處可下載)。

9、系列文章

《跟著源碼學(xué)IM(一):手把手教你用Netty實現(xiàn)心跳機(jī)制、斷線重連機(jī)制》

《跟著源碼學(xué)IM(二):自已開發(fā)IM很難?手把手教你擼一個Andriod版IM》

《跟著源碼學(xué)IM(三):基于Netty,從零開發(fā)一個IM服務(wù)端》

《跟著源碼學(xué)IM(四):拿起鍵盤就是干,教你徒手開發(fā)一套分布式IM系統(tǒng)》

《跟著源碼學(xué)IM(五):正確理解IM長連接、心跳及重連機(jī)制,并動手實現(xiàn)》

《跟著源碼學(xué)IM(六):手把手教你用Go快速搭建高性能、可擴(kuò)展的IM系統(tǒng)》

《跟著源碼學(xué)IM(七):手把手教你用WebSocket打造Web端IM聊天》

《跟著源碼學(xué)IM(八):萬字長文,手把手教你用Netty打造IM聊天》

《跟著源碼學(xué)IM(九):基于Netty實現(xiàn)一套分布式IM系統(tǒng)》(* 本文)

10、參考資料

[1]?新手入門:目前為止最透徹的的Netty高性能原理和框架架構(gòu)解析

[2]?寫給初學(xué)者:Java高性能NIO框架Netty的學(xué)習(xí)方法和進(jìn)階策略

[3]?史上最強(qiáng)Java NIO入門:擔(dān)心從入門到放棄的,請讀這篇!

[4]?Java的BIO和NIO很難懂?用代碼實踐給你看,再不懂我轉(zhuǎn)行!

[5]?史上最通俗Netty框架入門長文:基本介紹、環(huán)境搭建、動手實戰(zhàn)

[6]?理論聯(lián)系實際:一套典型的IM通信協(xié)議設(shè)計詳解

[7]?淺談IM系統(tǒng)的架構(gòu)設(shè)計

[8]?簡述移動端IM開發(fā)的那些坑:架構(gòu)設(shè)計、通信協(xié)議和客戶端

[9]?一套海量在線用戶的移動端IM架構(gòu)設(shè)計實踐分享(含詳細(xì)圖文)

[10]?一套原創(chuàng)分布式即時通訊(IM)系統(tǒng)理論架構(gòu)方案

[11]一套高可用、易伸縮、高并發(fā)的IM群聊、單聊架構(gòu)方案設(shè)計實踐

[12]?一套億級用戶的IM架構(gòu)技術(shù)干貨(上篇):整體架構(gòu)、服務(wù)拆分等

[13]?一套億級用戶的IM架構(gòu)技術(shù)干貨(下篇):可靠性、有序性、弱網(wǎng)優(yōu)化等

[14]?從新手到專家:如何設(shè)計一套億級消息量的分布式IM系統(tǒng)

[15]?基于實踐:一套百萬消息量小規(guī)模IM系統(tǒng)技術(shù)要點總結(jié)

(本文已同步發(fā)布于:http://www.52im.net/thread-3789-1-1.html)


跟著源碼學(xué)IM(九):基于Netty實現(xiàn)一套分布式IM系統(tǒng)的評論 (共 條)

分享到微博請遵守國家法律
饶阳县| 林州市| 称多县| 凯里市| 楚雄市| 克拉玛依市| 梓潼县| 万山特区| 湘潭市| 茂名市| 凌云县| 金沙县| 会东县| 凭祥市| 罗山县| 张家港市| 三都| 策勒县| 贞丰县| 牡丹江市| 阳朔县| 延边| 措美县| 金溪县| 秭归县| 万荣县| 扶风县| 泗水县| 望都县| 南华县| 宝坻区| 大埔县| 黎城县| 平远县| 华阴市| 阜新市| 县级市| 沅陵县| 沿河| 保定市| 临朐县|