長(zhǎng)沙網(wǎng)站開發(fā)長(zhǎng)沙網(wǎng)站建設(shè)軟文營(yíng)銷案例文章
首先附上項(xiàng)目介紹,后面詳細(xì)解釋技術(shù)細(xì)節(jié)
1. chat-websocket
一個(gè)基于Vue3和WebSocket的簡(jiǎn)易網(wǎng)絡(luò)聊天室項(xiàng)目,包括服務(wù)端和客戶端部分。
項(xiàng)目地址 websocket-chat
下面是項(xiàng)目的主要組成部分和功能:
項(xiàng)目結(jié)構(gòu)
chat-websocket/
|-- server/ # WebSocket 服務(wù)端
| |-- run.js # 服務(wù)端
| |-- DBManager.js #數(shù)據(jù)庫(kù)對(duì)象管理
|-- src/
| |-- components/
| | |-- ... # Vue 組件
| |-- assets/
| | |-- ... # 靜態(tài)資源
| |-- views/
| | |-- Home.vue # 主要視圖組件
| | |-- Login.vue # 登錄視圖組件
| |-- router/
| |-- App.vue
| |-- main.js
|-- public/
|-- README.md
|-- ...
功能特性
- 私聊功能:用戶可以選擇聯(lián)系人進(jìn)行一對(duì)一私聊,發(fā)送即時(shí)消息。
- 群聊功能:用戶可以加入群組,與群組成員進(jìn)行群聊。
- 修改用戶名:用戶可以在界面上直接修改自己的用戶名。
- 顯示在線(連接)狀態(tài)
- 重新連接: WebSocket 斷開連接后,用戶可以重新連接服務(wù)器, 重新連接后, 會(huì)加載之前的聊天記錄
技術(shù)棧
-
前端框架: 使用 Vue3 作為前端框架,Element Plus 用于 UI 組件。
-
后端框架: 后端使用 Node.js + Mysql 實(shí)現(xiàn),使用 WebSocket 庫(kù) ws 作為 WebSocket 服務(wù)端。
-
WebSocket: 實(shí)時(shí)通信使用 WebSocket 技術(shù),保證消息的實(shí)時(shí)性。
上面是項(xiàng)目介紹,下面介紹細(xì)節(jié)
2. 整體設(shè)計(jì)思路
- 前端使用Vue框架,快速搭建聊天室的原型,同時(shí)為了美觀,使用Element Plus 用于 UI 組件.
- 前端頁(yè)面 包含登陸頁(yè)面Login和聊天頁(yè)面Home
- 實(shí)時(shí)通信使用 WebSocket 技術(shù),客戶端發(fā)送請(qǐng)求,服務(wù)端結(jié)合數(shù)據(jù)庫(kù)進(jìn)行返回.
- 服務(wù)端使用Session機(jī)制,記錄
sessions[clientId]
,增加定時(shí)器定時(shí)清除session,用于24H過(guò)期機(jī)制. - 服務(wù)端直接使用ws庫(kù)建立連接,同時(shí)使用DBManager操作數(shù)據(jù)庫(kù)對(duì)象,完成數(shù)據(jù)處理和傳輸.
- 為了方便消息分類傳輸,定義
消息對(duì)象
,客戶端和服務(wù)端共有相同的消息對(duì)象.
一次簡(jiǎn)單的登陸到獲取消息的流程如圖:
一次簡(jiǎn)單的發(fā)送和獲取消息的流程如圖:
3. 前端設(shè)計(jì)實(shí)現(xiàn)
3.1 頁(yè)面設(shè)計(jì)實(shí)現(xiàn)
聊天室布局參考Element Plus提供的布局
其中頭部展示用戶信息狀態(tài), 左邊是群組和用戶選擇, 主界面就是聊天界面,展示聊天信息.
最終成品如下:
一些細(xì)節(jié)解釋
- 用戶頭像根據(jù)用戶名自動(dòng)生成,用到了ui組件.
-
可以顯示用戶當(dāng)前連接狀態(tài),當(dāng)鏈接斷開后,可以重新連接.
-
聊天信息包含三要素: 時(shí)間, 用戶名, 內(nèi)容, 如圖所示.通過(guò)v-if判斷消息放在左邊還是右邊
-
發(fā)送欄固定,且接收和發(fā)送消息后聊天窗口(列表)自動(dòng)到達(dá)底部.
3.2 登陸邏輯設(shè)計(jì)實(shí)現(xiàn)
進(jìn)入頁(yè)面后已經(jīng)建立websocket連接,單擊登陸后發(fā)送請(qǐng)求,若成功則接收到username
,uid
,session_id
,這三個(gè)參數(shù),直接以cookie的形式保存在本地.
后續(xù)進(jìn)入頁(yè)面,服務(wù)端都會(huì) 驗(yàn)證session,進(jìn)行持久化訪問(wèn).
3.3 聊天邏輯設(shè)計(jì)實(shí)現(xiàn)
- 前端共享使用相同的socket對(duì)象.
-
每次單擊群組或用戶,根據(jù)當(dāng)前選擇發(fā)送請(qǐng)求獲取接收不同類型消息
群組消息
用戶消息
-
還需要在進(jìn)入頁(yè)面后獲取用戶和群組列表進(jìn)行初始化
-
無(wú)論是接收到群組還是用戶消息,直接放入相同的列表,因?yàn)閮煞N消息只需要顯示三要素即可,后面分別解析
4. 后端設(shè)計(jì)實(shí)現(xiàn)
4.1 數(shù)據(jù)庫(kù)設(shè)計(jì)實(shí)現(xiàn)
設(shè)計(jì)數(shù)據(jù)庫(kù)包含如下表:
表名 | 列名 | 數(shù)據(jù)類型 | 說(shuō)明 |
---|---|---|---|
USER | uid | INTEGER | 用戶ID(主鍵,自增) |
name | VARCHAR(255) | 用戶名 | |
password | VARCHAR(255) | 用戶密碼 | |
GROUPS | gid | INTEGER | 群組ID(主鍵,自增) |
name | VARCHAR(255) | 群組名 | |
GMESSAGE | id | INTEGER | 消息ID(主鍵,自增) |
gid | INTEGER | 群組ID | |
uid | INTEGER | 發(fā)送消息的用戶ID | |
gname | VARCHAR(255) | 群組名 | |
text | TEXT | 消息內(nèi)容 | |
UMESSAGE | id | INTEGER | 消息ID(主鍵,自增) |
s_uid | INTEGER | 發(fā)送消息的用戶ID | |
r_uid | INTEGER | 接收消息的用戶ID | |
text | TEXT | 消息內(nèi)容 | |
time | TIMESTAMP | 消息發(fā)送時(shí)間 | |
GROUP_USER | uid | INTEGER | 用戶ID |
gid | INTEGER | 群組ID |
還有與各表對(duì)應(yīng)的管理類:
各表分別繼承管理類
這里使用 Promise 的方式可以更好地處理異步代碼
4.2 服務(wù)端設(shè)計(jì)實(shí)現(xiàn)
-
導(dǎo)入所需的模塊和類
entity.js
: 包含了用戶和消息的實(shí)體類定義。DBManager.js
: 包含了與數(shù)據(jù)庫(kù)交互的相關(guān)類。ws
: WebSocket 模塊。- 創(chuàng)建了一些表格和實(shí)體對(duì)象的實(shí)例,用于存儲(chǔ)和管理用戶、群組、消息等信息。
-
常量和變量定義
SESSION_EXPIRY_TIME
: 定義了會(huì)話過(guò)期時(shí)間,以毫秒為單位,用于定期檢查會(huì)話是否過(guò)期。Ws
: WebSocket 模塊的別名。clients
: 存儲(chǔ)WebSocket連接的對(duì)象。sessions
: 存儲(chǔ)用戶會(huì)話信息。
-
初始化WebSocket服務(wù)器
- 定義一些事件處理函數(shù),如
handleOpen
、handleClose
、handleConnection
等。 - 在
handleConnection
中,處理了用戶連接時(shí)的事件,包括消息的處理。
- 定義一些事件處理函數(shù),如
-
消息處理
handleMessage
函數(shù)用于處理收到的消息。根據(jù)消息類型進(jìn)行相應(yīng)的操作,包括群組聊天、獲取初始數(shù)據(jù)、私聊等。- 使用數(shù)據(jù)庫(kù)表格對(duì)象(如
groupTable
、gmessageTable
等)進(jìn)行消息的存儲(chǔ)和查詢。 - 通過(guò)WebSocket向指定用戶或群組發(fā)送消息。
-
用戶登錄
- 當(dāng)收到類型為
MessageType.MESSAGE_LOGIN
的消息時(shí),處理用戶登錄邏輯。 - 檢查用戶是否存在于數(shù)據(jù)庫(kù)中,若不存在則插入新用戶。
- 為用戶分配一個(gè)唯一的會(huì)話ID,將用戶信息存儲(chǔ)在
sessions
對(duì)象中。 - 向客戶端發(fā)送登錄成功消息,并攜帶用戶信息和會(huì)話ID。
- 當(dāng)收到類型為
sessions的保存形式如下:
sessions[clientId] = {uid: uid,username: msg.data.username,ws: this,creationTime: Date.now(),sessionID: clientId,};
定時(shí)器判斷是否過(guò)期
5. 展示
群組聊天
私聊
5. 小結(jié)
孟寧老師上課旁征博引,時(shí)不時(shí)與同學(xué)們互動(dòng) (指讓同學(xué)們發(fā)數(shù)字),無(wú)論是前端網(wǎng)絡(luò)編程,網(wǎng)絡(luò)協(xié)議RPC,還是Linux內(nèi)核網(wǎng)絡(luò)協(xié)議棧,似乎都信手拈來(lái),相信如果認(rèn)真聽課,加上自己的鉆研,絕對(duì)受益匪淺.
對(duì)于這門課程,完全可以說(shuō)是師傅領(lǐng)進(jìn)門,修行看個(gè)人了,我們深入其中某個(gè)方向,也會(huì)有所建樹.
此前只是接觸過(guò)JS和Vue,并未熟練掌握它們,這次由于課程原因,嘗試完全使用JS作為前后端代碼,沒(méi)有使用熟悉的Python和Java來(lái)構(gòu)建后端,算是對(duì)自己的一次挑戰(zhàn).幸好有chatgpt在細(xì)節(jié)上的協(xié)助,結(jié)合各類組件豐富的文檔,完成了這次項(xiàng)目.