很多技術人對聊天系統比較感興趣,當年馬哥,靠一個聊天系統搞出一個帝國,所以聊天系統對技術人心中總有一種好感。今天鋒哥推薦一個不錯的聊天開源聊天系統,大夥有空可以學習下,提高下;
github開源地址:
<code>https://github.com/Kanarienvogels/Chatroom/<code>
互聯網實時聊天系統 (Spring + Netty + Websocket)
0. 前言
最近一段時間在學習Netty網絡框架,又趁著計算機網絡的課程設計,決定以Netty為核心,以WebSocket為應用層通信協議做一個互聯網聊天系統,整體而言就像微信網頁版一樣,但考慮到這個聊天系統的功能非常多,因此只打算實現核心的聊天功能,包括單發、群發、文件發送,然後把項目與Spring整合做成開源、可拓展的方式,給大家參考、討論、使用,歡迎大家的指點。
關於Netty
Netty 是一個利用 Java 的高級網絡的能力,隱藏其背後的複雜性而提供一個易於使用的 API 的客戶端/服務器框架。
詳細的可參考閱讀該書的電子版
Essential Netty in Action 《Netty 實戰(精髓)》關於WebSocket通信協議
WebSocket是為了解決HTTP協議中通信只能由客戶端發起這個弊端而出現的,WebSocket基於HTTP5協議,借用HTTP進行握手、升級,能夠做到輕量的、高效的、雙向的在客戶端和服務端之間傳輸文本數據。
1. 技術準備
IDE:MyEclipse 2016JDK版本:1.8.0_121瀏覽器:谷歌瀏覽器、360瀏覽器(極速模式)(涉及網頁前端設計,後端開發表示很苦悶)涉及技術:Netty 4WebSocket + HTTPSpring MVC + SpringJQueryBootstrap 3 + Bootstrap-fileinputMaven 3.5Tomcat 8.02. 整體說明
2.1 設計思想
整個通信系統以Tomcat作為核心服務器運行,其下另外一個線程運行Netty WebSocket服務器,Tomcat服務器主要處理客戶登錄、個人信息管理等的HTTP類型請求(通常的業務類型),端口為8080,Netty WebSockt服務器主要處理用戶消息通信的WebSocket類型請求,端口為3333。用戶通過瀏覽器登錄後,瀏覽器會維持一個Session對象(有效時間30分鐘)來保持登錄狀態,Tomcat服務器會返回用戶的個人信息,同時記錄在線用戶,根據用戶id建立一條WebSocket連接並保存在後端以便進行實時通信。當一個用戶向另一用戶發起通信,服務器會根據消息內容中的對話方用戶id,找到保存的WebSocket連接,通過該連接發送消息,對方就能夠收到即時收到消息。當用戶註銷或退出時,釋放WebSocket連接,清空Session對象中的登錄狀態。
事實上Netty也可以用作一個HTTP服務器,而這裡使用Spring MVC處理HTTP請求是出於熟悉的緣故,也比較接近傳統開發的方式。
2.2 系統結構
系統採用B/S(Browser/Server),即瀏覽器/服務器的結構,主要事務邏輯在服務器端(Server)實現。借鑑MVC模式的思想,從上至下具體又分為視圖層(View)、控制層(Controller)、業務層(Service)、模型層(Model)、數據訪問層(Data Access)
2.3 項目結構
項目後端結構:
項目前端結構:
2.4 系統功能模塊
系統只包括兩個模塊:登錄模塊和聊天管理模塊。
登錄模塊:既然作為一個系統,那麼登錄的角色認證是必不可少的,這裡使用簡單、傳統的Session方式維持登錄狀態,當然也有對應的註銷功能,但這裡的註銷除了清空Session對象,還要釋放WebSocket連接,否則造成內存洩露。聊天管理模塊:系統的核心模塊,這部分主要使用Netty框架實現,功能包括信息、文件的單條和多條發送,也支持表情發送。其他模塊:如好友管理模塊、聊天記錄管理、註冊模塊等,我並沒有實現,有興趣的話可以自行實現,與傳統的開發方式類似。由於本系統涉及多個用戶狀態,有必要進行說明,下面給出本系統的用戶狀態轉換圖。
2.6 系統界面
系統聊天界面如下:
3. 核心編碼
這裡只說明需要注意的地方,詳細的請看源碼
3.1 Netty服務器啟動與關閉
當關閉Tomcat服務器時,也要釋放Netty相關資源,否則會造成內存洩漏,關閉方法如下面的close(),如果只是使用shutdownGracefully()方法的話,關閉時會報內存洩露Memory Leak異常(但IDE可能來不及輸出到控制檯)
描述 : Netty WebSocket 務器
使 用獨立的線 啟 動
@author Kanarien
@version 1.0
@date 2018年5 月 18日 午11 : 22 : 51
/
public class WebSocketServer implements Runnable {
/
描述 : 啟 動Netty Websocket 務器
/
public void build()
{
略,詳細請看源碼
}
/
描述 : 關閉Netty Websocket 務器主 要 是 釋 放 連接
連接 包 括 : 務器連接serverChannel
客戶端TCP 處 理 連接bossGroup
客戶端I / O操 作 連接workerGroup
若只 使 用
bossGroupFuture = bossGroup.shutdownGracefully();
workerGroupFuture = workerGroup.shutdownGracefully();
會 成 內存洩 漏 。
public void close()
{
serverChannelFuture.channel().close();
Future> bossGroupFuture = bossGroup.shutdownGracefully();
Future> workerGroupFuture = workerGroup.shutdownGracefully();
try {
bossGroupFuture.await();
workerGroupFuture.await();
} catch ( InterruptedException ignore ) {
ignore.printStackTrace();
}
}
}
4. 效果及操作演示
4.1 登錄操作
登錄入口為:http://localhost:8080/WebSocket/login 或 http://localhost:8080/WebSocket/ 當前系統用戶固定為9個,群組1個,包括9人用戶。
用戶1 用戶名:Member001 密碼:001用戶2 用戶名:Member002 密碼:002······用戶9 用戶名:Member009 密碼:0094.2 聊天演示
喜歡的話點點關注唄,後面持續更新更多幹貨
https://mp.weixin.qq.com/s/MGTxiKbPaw2159yM_FGiEA