教你六种方式实现聊天室
如果技術(shù)棧不一致的同學(xué)請(qǐng)盡量看懂架構(gòu)和概念,自己用自己的技術(shù)棧去架構(gòu)自己的聊天室!
此項(xiàng)目為前后端分離項(xiàng)目,基于vue+springboot構(gòu)建
歡迎star
前端:以 vue 為核心的 vue全家桶(vue+vuex-狀態(tài)管理+vue-router-路由管理+axios-HTTP庫),UI框架使用了iview+VueSax,打包和初始化項(xiàng)目工具使用 webpack 來代替vue-cli.圖片上傳使用了他人的 圖床,發(fā)送框使用了 quill 富文本編輯器。
后端:使用了springboot 框架,數(shù)據(jù)持久層框架使用了 mybatis,數(shù)據(jù)庫使用mysql.
中間件:緩存中間件-redis,消息隊(duì)列-rabbitmq。
加密使用 AES 加密
通訊協(xié)議使用 WebSocket和HTTP協(xié)議
項(xiàng)目演示:
1.登錄注冊(cè)部分
由于登錄注冊(cè)太過于簡單,所以這里直接給出賬號(hào)密碼名單使用
當(dāng)此賬號(hào)已經(jīng)登錄時(shí),isOnline 開關(guān)會(huì)顯示打開狀態(tài),點(diǎn)擊登錄會(huì)出現(xiàn)提示
切換另一個(gè)賬號(hào)即可,若無可用賬號(hào),請(qǐng)等待 orz
2.聊天
注:這個(gè)項(xiàng)目里只有群聊,沒有設(shè)置單人聊天,因單人聊天無非是群聊的一個(gè)特例,這里不予實(shí)現(xiàn)。
主界面
項(xiàng)目里給出了6個(gè)聊天室,分別對(duì)應(yīng)不同實(shí)現(xiàn)方式。
–聊天室一:
僅使用WebSocket實(shí)現(xiàn),僅能在線聊天,離線用戶收不到消息且無法讀取未讀消息
如圖,前端通過http協(xié)議向后端發(fā)送數(shù)據(jù),后端接收到數(shù)據(jù)后通過WebSocket協(xié)議向在線的人員發(fā)送數(shù)據(jù)。
–聊天室二:
使用`WebSocket+mysql`,提供了在線聊天,不在線用戶上線后可拉取未讀消息。
如圖,后端接收到聊天數(shù)據(jù)并給在線人員發(fā)送消息后再把數(shù)據(jù)按照一定的邏輯存在數(shù)據(jù)庫里,當(dāng)用戶上線后,拉取未讀消息即可,此時(shí)未讀消息能且僅能拉取一次,拉取完畢后,消息就成為已讀消息,并不能重讀拉取。
–聊天室三:
緩存寫擴(kuò)散:使用WebSocket+redis+mysql。
如圖,每個(gè)用戶維護(hù)一個(gè) inBox,每條信息發(fā)給服務(wù)器時(shí),給在線人員發(fā)生信息,并判斷該條消息所屬群組,并找到該群組下所有不在線人員,并把該消息寫入不在線人員下的inBox下,當(dāng)用戶上線拉取消息時(shí),只需從自己的 inBox 下拉取消息即可,該inBox是用redis的list實(shí)現(xiàn)的,是有序的(插入順序),所以不存在消息時(shí)間混亂問題,當(dāng)用戶讀取消息后,立即刪除該inBox,保證了未讀消息的唯一性.其中mysql用于消息的備份。
–聊天室四:
緩存讀擴(kuò)散:使用WebSocket+redis+mysql。
如圖,每個(gè)用戶需要維護(hù)一個(gè)outBox和一個(gè)已讀消息索引,用戶每發(fā)送一條信息,都存在自己的outBox里面,并存入order順序表,當(dāng)離線用戶上線拉取未讀消息時(shí),首先讀取自己已讀消息索引和order順序表,根據(jù)順序表大小和已讀消息索引之差找到自己所有未讀消息,然后根據(jù)順序表里的信息去找每一條信息發(fā)送者的outBox,并拉取每一條未讀消息,拉取完畢后更新自己的已讀消息索引即可。
–聊天室五:
緩存讀擴(kuò)散改良版:使用WebSocket+redis+mysql。
在上一個(gè)聊天室中,由于每個(gè)用戶有一個(gè)outBox,信息存儲(chǔ)將是無序的,所以需要額外耗費(fèi)空間來存儲(chǔ)順序,所以在改良版中,根據(jù)是群組的信息發(fā)送,所以只需維護(hù)一個(gè)群組的outBox,不再有個(gè)人的outBox,所以用戶拉取歷史消息時(shí),只需比對(duì)自己消息索引和群outBox索引即可
– 聊天室六
消息隊(duì)列:使用 WebSocket+Rabbitmq+mysql
這里使用rabbitmq作為消息中間件,每個(gè)群組是一個(gè)fanout 類型交換器,這個(gè)交換器的特點(diǎn)在于,每接收一條消息,交換器都會(huì)給綁定的隊(duì)列發(fā)送這條消息,所以每個(gè)群組綁定一個(gè)fanout類型交換器,每個(gè)交換器下都綁定這每個(gè)用戶的隊(duì)列,用戶每發(fā)送一條消息,每個(gè)隊(duì)列都會(huì)收到這條消息,在線的用戶把消息讀取出去,不在線的用戶上線拉取消息,這樣的方式減少了手動(dòng)判斷用戶和減少關(guān)注消息的順序問題,統(tǒng)一交給消息隊(duì)列處理。
三、其他
- UI優(yōu)化
登錄過期提醒
新消息提醒
發(fā)送圖片 - 消息存儲(chǔ)
前端所有消息均存在 localstorge中,當(dāng)前后登錄賬戶不一致時(shí),前一個(gè)賬戶消息將會(huì)被清空,如果前后登錄賬戶一致,消息不會(huì)清空
用戶登錄有效期在 30 分鐘內(nèi),超過30分鐘要重新登錄
總結(jié)
以上是生活随笔為你收集整理的教你六种方式实现聊天室的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经典炖鸡汤做法
- 下一篇: js-最常用的js表单校验1