即時通信應用服務,整套包含服務端、管理端和客戶端javascript
預計3篇分享:此次是第一篇,項目的總體介紹和實體關係的梳理前端
能夠註冊客戶端帳號,也可使用初始默認帳號,現有初始帳號說明:java
帳號 | 密碼 | 說明 |
---|---|---|
admin | 123456 | 管理端帳號 |
user | 123456 | 客戶端普通用戶帳號 |
muteuser | 123456 | 客戶端被禁言用戶帳號 |
disabled | 123456 | 客戶端被封禁用戶帳號 |
member1 | 123456 | 客戶端普通用戶帳號 |
member2 | 123456 | 客戶端普通用戶帳號 |
... | 123456 | 客戶端普通用戶帳號 |
member30 | 123456 | 客戶端普通用戶帳號 |
移動互聯網發展至今,以微信爲首的即時通信服務已經融入了咱們生活中的各個角落,在公司的一些業務中也扮演着重要的角色,對於即時通信咱們公司原來是使用的環信的服務,可是有不少定製化的需求沒法實現,因此後來決定內部開發一個知足定製化需求的即時通信微服務。node
使用socket.io
框架是由於當時後端缺人,加上看了一些例子後以爲使用起來真的很方便,並且全平臺支持,因此這個微服務就在前端團隊進行落地實踐,目前效果還不錯。mysql
社區目前這方面的內容比較少或者太簡陋(只有一個公共的聊天室這種)。另外就是在業務開發過程當中被 PM 搞得很難受,因此想脫離一些特有的業務上的東西,實現一個功能簡單五臟俱全的不摻雜公司業務的 IM 應用,包含服務端,管理端和客戶端。客戶端的模仿對象是微信,由於我很熟悉,不用在產品上面思考太多,另外就是試用的人很熟悉,不須要太多的溝通成本。git
要開發一套完整的即時通信服務,須要如下部分:github
爲企業級框架和應用而生web
選用阿里的 egg.js 框架作支撐,看中的緣由是他們內部大規模的落地和安全方面作得比較好,沒有選擇 nest 的緣由是集成 socket.io
比較麻煩,ORM 選用 sequelize,數據庫是 mysql ,以前一塊兒使用過,上手難度小sql
開箱即用的中臺前端/設計解決方案
選擇 Ant Design Pro 做爲模板開發管理端,選用的緣由是我對 Vue 全家桶比較熟悉,想借着這個機會熟悉下整套 React 生態 的開發流程,感覺下目前國內兩大開發框架的本質區別和異曲同工,Ant Design Pro 已經發布了好幾年了,也的確給中小型企業帶來效率的提高,也正好適合我這的需求。
🛠️ Vue.js 開發的標準工具
使用 @vue/cli 搭建 IM 服務的客戶端,一個移動端的 H5 項目,UI 框架使用的有贊 vant,集成了個人開源組件vue-page-stack和黃老師的better-scroll,實現 IM 的基礎功能
做爲一個前端工程師,大多數的平常工做是不須要思考實體關係的。可是,就個人實際體驗來看,懂得實體關係能夠幫助咱們更好的理解業務模型。而對產品和業務理解的提高對咱們的幫助是很是大的,能夠在需求評審的時候發現不少不符合邏輯的地方(怎麼又要吐槽產品經理了),這時候能提出來就會主動避免咱們在後續的過程當中進行反覆開發,同時能夠和產品側的同窗造成比較良好的互動(而不是互懟)。下面簡單羅列下比較重要的實體關係:
經過上圖能夠看到 user 是整個關係圖中的核心,下面介紹下各個實體之間的關係:
下面詳細介紹下會話、角色與權限:
完成一個即時通信應用,須要考慮的第一個事情就是會話,就是咱們微信裏面的對話窗口。思考會話和消息、用戶、羣組之間的關係花費了很多的精力,最終造成如下的基本關係:
也就是說,用戶和會話沒有直接的關係,只能經過用戶對應的單聊和羣聊去獲取會話,這樣作能夠有如下的好處:
爲了設計一個靈活、通用、方便的權限管理系統,本系統採用 RBAC(基於角色的訪問控制)控制,來設計一個通用的『用戶角色權限』平臺,方便後期擴展。
RBAC(基於角色的訪問控制)是指用戶經過角色與權限進行關聯。即一個用戶擁有若干角色,每個角色擁有若干權限(固然了,別把衝突的角色和權限配在一塊兒)。這樣,就構形成「用戶—角色—權限」的受權模型。在這種模型中,用戶與角色之間、角色與權限之間,通常是多對多的關係。
本系統默認有管理員、通常用戶、禁言用戶和封禁用戶這幾種角色,給不一樣的角色分配不一樣的權限,因此須要針對管理和發言等接口路由作一下統一的鑑權(經過中間件的方式)處理,具體方式和方法在後端項目中會詳細說明。本系統暫時採用預先定義了角色和權限的方式,後續想要擴展的話能夠編輯角色和權限。
沒見過微信的管理端,可是能夠想象一下,管理員能夠配置用戶的角色和權限,能夠編輯羣組的狀態:
註冊登陸後,能夠正常的添加好友和加入羣組,能夠修改我的基礎信息和處理申請
沒法登陸
舉個例子:如今有一個新版的我的中心須要上線測試,首先新建一個角色『測試我的中心』,再給這個角色分配對應的權限;而後給普通用戶作個分組,選出一些人配置上這個角色,這樣就能夠進行測試了。
下面說下即時通信服務的核心通信原理,和通常的 http 服務同樣,有一個服務端和客戶端進行通信,只不過詳細的協議和處理方式不同。
因爲歷史緣由,如今主流的 http 協議是無狀態協議(HTTP2 暫時應用不普遍),通常狀況是由客戶端主動發起請求,而後服務端去響應。那麼爲了實現服務端向客戶端推送信息,就須要前端主動向後端去輪詢,這種方式低效且容易出錯,在以前咱們的管理端首頁確實是這麼作的(5s 一次)。
爲了實現這種服務端主動推送信息的需求, HTML5 開始提供一種在單個 TCP 鏈接上進行全雙工通信的協議,也就是 WebSocket。WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端主動向客戶端推送數據。WebSocket 協議在 2008 年誕生,2011 年成爲國際標準,目前絕大部分瀏覽器都已經支持了。
WebSocket 的用法至關簡單:
var ws = new WebSocket("wss://echo.websocket.org");
ws.onopen = function(evt) { console.log("Connection open ..."); ws.send("Hello WebSockets!"); }; ws.onmessage = function(evt) { console.log( "Received Message: " + evt.data); ws.close(); }; ws.onclose = function(evt) { console.log("Connection closed."); }; 複製代碼
有了 WebSocket 協議讓服務端主動推送信息有了先進的武器,那麼有沒有什麼方式能夠兼容新舊瀏覽器呢?其實不少人想到了這點,答案就是socket.io
socket.io
socket.io
進一步封裝了WebSocket
的接口,並且能夠在舊版本瀏覽器中自主切換到使用輪詢的方式進行通信(咱們使用者是不會感知的),造成了一套統一的接口,大大減輕了開發的負擔。主要具備如下優勢:
最快,最可靠的即時通信引擎(FEATURING THE FASTEST AND MOST RELIABLE REAL-TIME ENGINE)
使用起來真的很簡單:
var io = require('socket.io')(80);
var cfg = require('./config.json'); var tw = require('node-tweet-stream')(cfg); tw.track('socket.io'); tw.track('javascript'); tw.on('tweet', function(tweet){ io.emit('tweet', tweet); }); 複製代碼
有了以上的基礎,咱們就基本完成了開始寫代碼以前的準備:明確了這個應用的基礎功能和實體之間的關係,也明確了基礎的技術方案選型,劃分了3個項目的各自任務。下面就開始完成 server 端吧
未完待續:下一篇介紹 server 端