java 聊天室WeChat

功能和特性

  • 基於socket實現的c/s架構的的通訊
  • 服務器和客戶心跳鏈接
  • gson實現的消息通訊機制
  • 註冊及登陸
  • 支持私聊和羣聊。
  • 動態更新用戶列表以及用戶消息提示
  • 支持emoji表情,以及emoji表情選擇器
  • 服務器端數據庫用戶記錄
  • 實現文件傳輸
  • 文件記錄

功能展現

  • login
  • chatroom


  • 表情包
  • 數據庫

總體架構

  • 使用了比較簡單的worker-master架構。java

    • 由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

  • 啓動環節
    • 服務器前先查詢數據庫,從中加載出用戶列表到內存。android

      (注:這樣的方式在數據較大時不合適,應該設計好數據庫的消息存儲機制,避免服務器端的數據量大時出現問題,這個小程序由於以前在設計的時候原本沒有加上數據庫的打算,後期加入後,也不想再次重構服務器端)ios

    • 數據庫已經封裝成Dao層,使用雙重鎖的單例模式進行控制訪問git

  • 用戶信息存儲及轉發
    • 用戶信息存儲倉的設置
      serverUser的實體bean在設計時採用的是 ConcurrentLinkedQueue做爲信息存儲倉的數據結構,保證在多線程下的安全。
    • 每次server端讀取client端發送的comment將數據發送到對應user的warehouse(數據倉)中,接着讀取其控制用戶的warehouse,執行命令。

client

  • 總體基本架構爲MVC
    model層經過control進行數據交互同時control層進行login和chatroom界面切換控制。
  • 基本界面切換
    以前對javafx不熟悉,根據寫andorid經驗,總以爲Javafx的界面切換不是很方便。初期將界面寫了出來,後期進行了界面切換方式的修改。
    參考JavaFX - 實現管理多個Stage窗口及源碼解析

一些值得注意的問題

  • gson的使用

    gson 的好用沒必要多說,寫的時候發現一個小問題gson 在使用時會將Integer以及int都會轉爲Double或者double類型
    解決方案以下解決gson將Integer默認轉換成Double的問題github

  • javafx UI界面更新

    • 相似於android在UI界面只能在UI線程中進行更改,在javafx中也是如此。不過以前Android知道其異步方式的實現
      在javafx中查閱資料後總結下其更改界面的方法數據庫

      Platform.runLater(new Task<String>() {
        @Override
        protected String call() throws Exception {
           //do UI operato
            return null;
        }
      });

      文件路徑

      在寫圖片的顯示時發現了顯示的問題,特意的查了這部分的材料,其中比較好的幾篇
      Java中文件的相對路徑與絕對路徑
      Java中文件路徑及其訪問json

      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,顯示的表情以表情簡寫表示

項目地址We Chat

相關文章
相關標籤/搜索