歡迎閱讀我的開源項目《迷你微信》服務器與《迷你微信》客戶端
在一個程序的迭代過程中,復雜度漸漸上升,可能會出現一些跨模塊的調用的需求,若是直接得到引用來進行使用,會導致模塊間的耦合度越來越高,消息機制是一種用于解耦這種耦合度高模塊的好方法,它的使用非常靈活便利,可以解決一對多(一個發送者,多個接受者)和需求頻繁的變更,甚至于,在添加新的需求時可以完全的不改動舊的代碼。在java中消息機制可以用觀察者模式來實現。
前緣未了在【迷你微信】基于MINA、Hibernatye、Spring、Protobuf的即時聊天系統:7.項目介紹之架構中,我們說道了在發送聊天消息時,可能出現接受者不在線的情況,因為可能出現的各種復雜情況,封裝到我們將發送消息這個行為ServerModel_Chatting類中。
不知道大家有沒有注意到,微信的聊天消息是可能發送失敗的,也許因為網絡問題,也許因為對方根本沒有開啟微信,若是像登陸、注冊等請求,服務器向客戶端發包失敗,想偷懶的話,是可以不作處理的,不僅因為這種事件發生的幾率較少,也是因為這種異常的拋棄不會造成不可接受的后果,大不了再點擊一次登陸咯。但是,請想象一下,若是您的好友給您發了一條消息,因為您的一時網絡問題,服務器不能成功的發送給您,就將其直接拋棄,那么……您可能被您的友人認為是無視了他的消息,這種后果是不可接受的。
所以,我們要對發送失敗的消息進行存儲,并在對方上線后及時的推送過去,這個模塊是比較復雜的,而且牽扯到復用(單聊、群聊)問題,還有存儲為永久數據問題,所以我們將其獨立成單獨的一個類來處理。在ServerModel_Chatting類的sendChatting方法中我們首先要從ServerModel中查找接受者是否在線,在線則可以直接推送;而不在線的情況下,則需要暫時存儲下來,等待接受者上線。
// 發送一條聊天消息public void sendChatting(final Chatting chattings) {ClientUser clientUser = serverModel.getClientUserByUserId(chattings.getReceiverUserId());// 如果不在線,則暫存if (clientUser == null){addChatting(chattings);return;}// 發送}// 暫存一條消息public void addChatting(Chatting chatting) {// 保存消息}
可以看到,發送聊天消息這個過程中,首先會判斷接受者是否在線,若是不在線會將消息暫存,在接受者上線后將接收到服務器推送的消息。然而,這個模塊如何知道接受者上線了呢?我們通過觀察者模式,在用戶登陸時通知本模塊進行查詢是否有為接收消息。
觀察者模式觀察者模式中,首先要有被觀察者和觀察者兩個角色(可以有多個觀察者,俗稱”圍觀“(⊙o⊙)…),被觀察者要繼承Observable類,觀察者要對被觀察者對象調用addObserver 方法。
此處代碼皆為刪減版,欲查看完整代碼,請參考開源項目《迷你微信》服務器
先說說我們如何在用戶登陸時通知消息發送模塊進行查驗。1.在Server_User的 login方法中,用戶登陸成功時,會調用ServerModel的 clientUserLogin 方法,
public void clientUserLogin(ClientUser clientUser, String userId) {// 保存用戶信息clientUser.onLine = true;clientUser.userId = userId;clientUserIdTable.put(userId, clientUser);// 通知變更setChange();notifyObservers(new ObserverMessage_Login(clientUser.iosession, userId));}
在上面的方法中,我們將自己設置為變更狀態,然后通知所有觀察者。
2.觀察者ServerModel_Chatting添加監聽并進行處理
serverModel.addObserver(new Observer() {@Overridepublic void update(Observable o, Object arg) {ObserverMessage om = (ObserverMessage) arg;if (om.type == ObserverMessage.Type.Login) {// 發送登陸者未接收的消息}}}
在這里,我們對serverModel的實例化對象添加了一個監聽,判斷是否為監聽事件,若是,則發送未接收的消息。
后話其實在本項目中,使用觀察者模式并不是一個好的做法,理由如下:
因為帖主的這個項目中,目前只有這一個點需要用到這樣一種功能,所以偷了個懶。一旦需求復雜度提升,我們需要將觀察者模式做一些變化,將其做成完整的消息機制,使其具備一下幾個特點:
帖主的想法如下:
歡迎閱讀我的開源項目《迷你微信》服務器與《迷你微信》客戶端
新聞熱點
疑難解答