WebSocket乾貨-2 實現1對1聊天 離線訊息
阿新 • • 發佈:2021-06-18
上篇文章已實現基礎的群聊功能 將收到的資訊轉發到所有人。
先隨便聊一下
首先是 實現思路 一開始是想把WebSocket物件整個賽進Redis中 但是遇見了問題 WebSocket無法反序列化 因此無法存進Redis。所以只能繼續用CopyOnWriteArraySet對付使用了.(在想到更好的解決方案之前可能要一直用他了)
首先最先要處理的是 OnMessage 註解下的OnMessage方法 其中有這樣一個引數String Message 收到的包 ----我們在這裡改裝下 前端發包的時候發JSON字串
{
type:"型別"
conent:“內容”
sid:"傳送的目標Id"
tid:"您自己的id"
}
根據這個json 我們就可以去CopyOnWriteArraySet取得目標使用者的Session 然後對他傳送訊息 sendText;
至此 1 - 1的聊天就實現了
之後就是離線訊息
同上如果在CopyOnWriteArraySet中娶不到sid對應的session 那就說明使用者不存在Or離線
那我們就把該條訊息存入Redis 中
在使用者連線進入時 @Onopen註解下的Onopen方法
根據使用者的sid判斷是否有離線訊息
如果有 返送給使用者 同時刪除Redis中未讀訊息的快取
貼程式碼
/** * 資料處理中心 * * @param message * @param session */ @OnMessage public void OnMessage(String message, Session session) { if (isMessageType(message) == -1) { log.error("訊息來源異常 ---- 訊息來源ID" + this.sid); return; } else if (isMessageType(message) == 0) { sendMsgBach(message); } else if (isMessageType(message) == 1) { //處理1對1訊息 當前收到訊息來源session sendMsg(message, session); } }
/** * 判斷訊息型別 為公開訊息 還是私有訊息 */ public Integer isMessageType(String msg) { JSONObject jsonObject = JSONObject.parseObject(msg); Integer type = jsonObject.getInteger("type"); if (type == 1) { return 1; } else if (type == 0) { return 0; } else { return -1; } }
/** * @param messagem 訊息 */ public void sendMsg(String messagem, Session session) { Boolean sign = false; JSONObject jsonObject = JSONObject.parseObject(messagem); String sid = jsonObject.getString("sid"); System.out.println("當前使用者id:" + this.sid); System.out.println("目標使用者id:" + sid); //先給傳送端返回傳送的訊息 try { session.getBasicRemote().sendText(messagem); } catch (IOException e) { e.printStackTrace(); } for (WebSocketServer iserver : webSocketSet) { if (sid.equals(iserver.sid) ) { try { iserver.session.getBasicRemote().sendText(messagem); sign = true; } catch (IOException e) { e.printStackTrace(); } } } //處理未成功傳送的訊息 if (sign == false) { BoundListOperations boundListOperations = redisTemplate.boundListOps("unread:" + sid); String content = (String) jsonObject.get("content"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss"); String format = simpleDateFormat.format(new Date()); content="離線訊息 - "+format+" "+content; jsonObject.put("content",content); boundListOperations.leftPush(jsonObject.toJSONString()); } }