[toc] 功能和特性 基於socket實現的c/s架構的的通信 伺服器和客戶心跳連接 gson實現的消息通信機制 註冊及登錄 支持私聊和群聊。 動態更新用戶列表以及用戶消息提示 支持emoji表情,以及emoji表情選擇器 伺服器端資料庫用戶記錄 ~~實現文件傳輸~~ ~~文件記錄~~ 功能展示 ...
[toc]
功能和特性
- 基於socket實現的c/s架構的的通信
- 伺服器和客戶心跳連接
- gson實現的消息通信機制
- 註冊及登錄
- 支持私聊和群聊。
- 動態更新用戶列表以及用戶消息提示
- 支持emoji表情,以及emoji表情選擇器
- 伺服器端資料庫用戶記錄
實現文件傳輸文件記錄
功能展示
- login
- chatroom
- 表情包
- 資料庫
整體架構
使用了比較簡單的worker-master架構。
- 由masterserve進行事件的分發
- 由workserver具體的管理單個用戶的消息請求
- 相關模型鏈接 Master-Worker模式
- 消息機制
- 採用json作為通信載體,後期功能性的更改較為簡單
通信命令字設計如下
public final static boolean SINGLE = true;
public final static boolean GROUP = false;
/**
* status
*/
public final static int SUCCESS = 0x01;
public final static int FAILED = 0x02;
/**
* message
*/
public static Integer COMMAND = 0x10;
public static Integer TIME = 0x11;
public static Integer USERNAME = 0x12;
public static Integer PASSWORD = 0x13;
public static Integer SPEAKER = 0x14;
public static Integer RECEIVER = 0x15;
public static Integer CONTENT= 0x16;
/**
* command
*/
public final static int COM_LOGIN = 0x20;
public final static int COM_SIGNUP = 0x21;
public final static int COM_RESULT = 0x22;
public final static int COM_DESCRIPTION = 0x23;
public final static int COM_LOGOUT =0x24;
public final static int COM_CHATWITH = 0x25;
public final static int COM_GROUP = 0x26;
public final static int COM_CHATALL = 0x27;
public final static int COM_KEEP = 0x28;
public final static int COM_MESSAGEALL = 0X29;
基本響應流程概述
- Client->Server
- 請求註冊(已註冊用戶請求登錄),請求登錄狀態
- 聊天命令分為單人和多人群聊
- Server->Client
- 返回登錄|註冊成功反饋
- 返回登錄|註冊失敗反饋,及失敗原因(用戶已經註冊|用戶尚未註冊|密碼錯誤|伺服器連接失敗等...)
- 每個用戶登錄廣播用戶集
- 提取數據倉發送消息給指定用戶
- 廣播信息
心跳連接
之前考慮上線下線方式的時候想到的一個辦法是,下線的時候給伺服器發送下線通知,後面考慮了出現斷網等突發情況時這樣的設計將出現問題。所以採用了心跳連接的方式。- server端採用了以時間差為判斷方式的連接判斷方式,通過具體的實踐server端的實踐差為2000ms較為合適.
- client維持了500ms的心跳
Server
- 啟動環節
伺服器前先查詢資料庫,從中載入出用戶列表到記憶體。
(註:這樣的方式在數據較大時不合適,應該設計好資料庫的消息存儲機制,避免伺服器端的數據量大時出現問題,這個小程式因為之前在設計的時候本來沒有加上資料庫的打算,後期加入後,也不想再次重構伺服器端)
資料庫已經封裝成Dao層,使用雙重鎖的單例模式進行控制訪問
- 用戶信息存儲及轉發
- 用戶信息存儲倉的設置
serverUser的實體bean在設計時採用的是 ConcurrentLinkedQueue作為信息存儲倉的數據結構,保證在多線程下的安全。 每次server端讀取client端發送的comment將數據發送到對應user的warehouse(數據倉)中,接著讀取其控制用戶的warehouse,執行命令。
client
- 整體基本架構為MVC
model層通過control在login和chatroom界面進行數據交互。 - 基本界面切換
之前對javafx不熟悉,根據寫andorid經驗,總覺得Javafx的界面切換不是很方便。初期將界面寫了出來,後期進行了界面切換方式的修改。
參考JavaFX - 實現管理多個Stage視窗及源碼解析
一些值得註意的問題
gson的使用
gson 的好用不必多說,寫的時候發現一個小問題gson 在使用時會將Integer以及int都會轉為Double或者double類型
解決方案如下解決gson將Integer預設轉換成Double的問題javafx UI界面更新
類似於android在UI界面只能在UI線程中進行更改,在javafx中也是如此。不過之前Android知道其非同步方式的實現
在javafx中查閱資料後總結下其更改界面的方法java Platform.runLater(new Task<String>() { @Override protected String call() throws Exception { //do UI operato return null; } });
文件路徑
在寫圖片的顯示時發現了顯示的問題,特地的查了這部分的材料,其中比較好的幾篇
Java中文件的相對路徑與絕對路徑
Java中文件路徑及其訪問emoji表情的實現
方案1 傳統emoji的表情的實現
其實早在2010年,Unicode編碼就已經納入了700多個Emoji表情,所以是可以支持表情的,只要載入支持Emoji表情的字型檔即可 鏈接How to support Emojis (Part1)
但是emoji的顯示時要依賴於平臺的,之前在Android端寫過的emoji實現由於和ios端不統一也重新定製了一份
- 附上對比
Android
javafx
簡直要醜哭了
- 實現方式
emoji 的編碼方式
java中String 採用 UTF-16 編碼方式存儲所有字元, getBytes(String charsetName)也就是轉為UTF-8 即可實現編碼轉換。將其輸出即可顯示emoji - 方案2 之前在Android端通過對SpannableString 的處理實現添加任何的圖片到文本中
根據這個思路 參考EmojiOneJava實現了功能.
而且javafx的textArea不支持 文字加圖片, 在java分fx中textflow可以存放子組件,所以顯示界面使用textflow,輸入界面使用textArea,顯示的表情以表情簡寫表示