java基于websocket實現(xiàn)im聊天功能
前言
文字聊天應(yīng)該是很多人每天常用的功能,這篇文章就來分析一下聊天是怎么創(chuàng)建的,他的底層邏輯是什么,以及如何實現(xiàn)他的底層邏輯。設(shè)計實現(xiàn)消息的發(fā)送過程就像這張圖一樣,經(jīng)過websocket進行一個消息的轉(zhuǎn)發(fā),一對一是這樣,在群里里面發(fā)消息也是這個邏輯,一個消息發(fā)送給多個人。本質(zhì)是也是一對一聊天,只是邏輯的干預(yù)是你覺得他就是一對多群聊。
用戶緩存的核心代碼,緩存用戶連接。SessionCache封裝了用戶的信息和客戶端連接的引用。
/** * 保存sessionId與用戶的map */ Map<String, SessionCache> sessionCacheMap = new ConcurrentHashMap<>();
當(dāng)用戶登錄的時候建立websocket長連接并且把連接信息存入到本地緩存,當(dāng)有用戶給他發(fā)消息的時候進行一個消息轉(zhuǎn)發(fā)。
public void wsOpen(WebSocketSession session) throws IOException { CacheToken cache = validateTokenAndReturnCache(session, tokenCache); if (cache == null) return; log.info("websocket id:{} 建立連接,用戶token:{} 連接成功,放入在線用戶緩存", session.getId(), cache.getToken()); javsessionCacheMap.put(session.getId(), new SessionCache(cache.getToken(), session)); }
當(dāng)用戶下線之后的代碼,從本地清除緩存,如果有用戶給他發(fā)消息就存入到緩存。
/** * 關(guān)閉連接清除緩存 * @param sessionId * @return */ public void wsClose(String sessionId) { SessionCache sessionCache = sessionCacheMap.remove( sessionId ); }
發(fā)送消息的代碼,當(dāng)消息過來獲取緩存中的WebSocketSession進行一個字節(jié)流的邏輯寫入。
/** * 發(fā)送消息的方法 * @param session * @param payload * @return */ public boolean sendData(WebSocketSession session, String payload){ if (session == null || !session.isOpen()) { return false; } try { if (session.isOpen()) { session.sendMessage(new TextMessage(payload)); return true; } else { // 連接關(guān)閉,丟棄消息 // String token = (String) session.getAttributes().get("token"); // log.debug( "websocket id:{} 已經(jīng)關(guān)閉, token:{}, 丟棄消息。", session.getId(), token); // log.debug("websocket關(guān)閉丟棄消息:{}", payload); return false; } } catch (IOException e) { if (e instanceof IOException || e instanceof SocketTimeoutException) { log.info("發(fā)送消息報錯:session.isOpen():{} ERROR: {}", session != null ? session.isOpen() : null, e.getMessage()); } else { log.error("發(fā)送消息報錯:session.isOpen():{}", session != null ? session.isOpen() : null, e); } return false; } }
消息體
消息體常見的消息分為文字消息,圖片消息還有語音消息。這里暫且不說視頻流。也就是我們常用的視頻聊天。首先從最基本的文字,圖片和語音來說,到后臺這邊都是使用的JSON格式。文字就不用說了,圖片的話是經(jīng)過一個第三方的存儲文件服務(wù)器轉(zhuǎn)換成的一個鏈接。然后用戶端進行一個渲染。然后才會看到常用的一些圖片。然后語音消息其實也是一段文憑。音頻其實也是一個文件。到文件服務(wù)器之后也是一個文件的鏈接,然后用戶端進去。格式進行一個轉(zhuǎn)換。最后呈現(xiàn)給用戶的就是一段語音。
敏感字的處理
這里要說的有一個點,就是一個敏感字的處理。其實敏感字的檢索這就涉及到一些算法的操作。我們可能需要查看某一段文字當(dāng)中是不是有一些敏感字?在常見的操作當(dāng)然是使用字符檢索一下,也可以使用一些專門的檢索算法,當(dāng)然邏輯上每一個系統(tǒng)里面會有一張專門用來配置的敏感字目錄,存在敏感字。進行拒絕或者打碼操作。
總結(jié)
這里解釋了最簡單的語音聊天的一個。實現(xiàn)當(dāng)你用戶量變得很大的時候,可能已經(jīng)滿足不了需求。需要用到Netty進行一個性能的提升。這是后話大道至簡,其實越復(fù)雜的東西是靠著簡單的功能一點點往上面疊加而產(chǎn)生的,一對一的聊天,本質(zhì)上就是數(shù)據(jù)的傳遞。
引用 http://chabaoo.cn/article/127969.htm
以上就是java基于websocket實現(xiàn)im聊天的詳細(xì)內(nèi)容,更多關(guān)于java websocket實現(xiàn)im聊天的資料請關(guān)注腳本之家其它相關(guān)文章!
- Java實現(xiàn)使用Websocket發(fā)送消息詳細(xì)代碼舉例
- 如何在Java中使用WebSocket協(xié)議
- springboot整合websocket后啟動報錯(javax.websocket.server.ServerContainer not available)
- Java實現(xiàn)WebSocket四個步驟
- java中Websocket的使用方法例子
- Java?spring?MVC環(huán)境中實現(xiàn)WebSocket的示例代碼
- Java中實現(xiàn)WebSocket方法詳解
- 教你如何使用Java實現(xiàn)WebSocket
- 一步步教你如何使用Java實現(xiàn)WebSocket
- Java應(yīng)用層協(xié)議WebSocket實現(xiàn)消息推送
- java?WebSocket?服務(wù)端實現(xiàn)代碼
- Java中使用WebSocket的幾種方式
相關(guān)文章
Java實戰(zhàn)之實現(xiàn)文件資料上傳并生成縮略圖
這篇文章主要介紹了通過Java實現(xiàn)文件資料的上傳并生成一個縮略圖,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Java有一定的幫助,感興趣的小伙伴可以了解一下2021-12-12Java中基于DeferredResult的異步服務(wù)詳解
這篇文章主要介紹了Java中基于DeferredResult的異步服務(wù)詳解,DeferredResult字面意思是"延遲結(jié)果",它允許Spring MVC收到請求后,立即釋放(歸還)容器線程,以便容器可以接收更多的外部請求,提升吞吐量,需要的朋友可以參考下2023-12-12java實現(xiàn)相同屬性名稱及相似類型的pojo、dto、vo等互轉(zhuǎn)操作
這篇文章主要介紹了java實現(xiàn)相同屬性名稱及相似類型的pojo、dto、vo等互轉(zhuǎn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08關(guān)于springboot集成swagger及knife4j的增強問題
這篇文章主要介紹了springboot集成swagger以及knife4j的增強,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03Java Spring MVC獲取請求數(shù)據(jù)詳解操作
Spring MVC 是 Spring 提供的一個基于 MVC 設(shè)計模式的輕量級 Web 開發(fā)框架,本質(zhì)上相當(dāng)于 Servlet,Spring MVC 角色劃分清晰,分工明細(xì)。由于 Spring MVC 本身就是 Spring 框架的一部分,可以說和 Spring 框架是無縫集成2021-11-11