上次講了websoket
的基礎知識和應用插件,今天我們來用websocket
來實現一個聊天程序。先看幾張界面截圖:
聊天界面:
歷史消息查看:
用戶上線提醒:
在線體驗地址:地址
功能結構圖
可以看到,該聊天室主要分為三個部分:消息實時推送,聊天界面與交互實現,用戶認證模塊。下面講講這個3個模塊的實現方式。
整體架構
前端:vue-cli
搭建+websock
客戶端
后端:nodeJs
+websock
服務端+JWT
認證
消息推送模塊實現
主要用到了websock
的雙工通信功能:
服務端核心代碼:
const sendDataType = {
// 發送消息
sendMsg: 1,
// 發送在線用戶數
userOnlineCount: 2,
// 發送用戶身份信息
sendName: 3,
// 發送在線用戶列表
sendUserList: 4
}
Object.freeze(sendDataType)
class WsChat {
constructor(port = 30002) {
this.wss = new WebSocket.Server(
{port: port
},
);
// 連接成功,初始化事件
this.wss.on('connection', (ws, req) => {
this.initWsEvent(ws)
});
}
initWsEvent(ws) {
//收到消息
ws.on('message', message => {
logger.writeInfo('message', message)
this.onMessage(message, ws)
});
ws.on("close", () => {
//將已經斷開的,刪除掉
this.onClose()
});
}
}
上面的代碼不難看出,服務端定義了一個枚舉:sendDataType
來告訴客戶端收到消息的類型,分別是:
1: 收到新消息
2: 收到在線用戶數量的通知
3: 收到用戶身份信息
4: 收到在線用戶列表
客戶端核心代碼:
this.ws = new WebSocket("ws://127.0.0.1:8020");
this.ws.addEventListener('open', () => {
// 向服務端發送連接通知
this.ws.send(JSON.stringify({type: 'connection', data: {userId, token, name}}));
})
this.ws.addEventListener('message', (evt) => {
// 收到服務端消息,根據定義的類型判斷
}
this.ws.addEventListener('error', (error) => {
// 連接失敗,給出提示
new NoticeJs({
type: 'error',
title: '連接失敗',
text: 'socket服務連接失敗,當前屬於離線狀態!',
position: 'topCenter'
}).show()
})
客戶端向服務端推送消息同樣定義了枚舉來讓服務端區分客戶端的消息類型:
changeName:表示用戶發起改名請求(服務端會將新名稱推送給其他用戶)
connection:客戶端的第一次連接(服務端會將用戶的token和基本信息返回給用戶)
msg:表示客戶端向某一用戶發送消息(服務端會將該消息發給對應的用戶)
服務端和客戶端相互約定好消息類型,根據不同的類型做出不同的響應,這樣就能完成我們的第一個核心功能--實時通訊
客戶端交互界面實現
該部分主要分為用戶列表,用戶交互,消息展示三個部分。主要是用vue
來渲染的,樣式部分沒有用第三方的庫,消息展示用到了localStorage
,它們主要是:
// 緩存所有用戶本地聊天記錄
localStorage.setItem('ws_allMsgMap', JSON.stringify(this.allMsgMap))
// 緩存用戶信息
localStorage.setItem('ws_user_info', JSON.stringify({userId, token}))
// 緩存歷史用戶列表
localStorage.setItem('ws_userList', JSON.stringify(this.userList))
因為本應用沒有加入數據庫,所以用h5的緩存技術來緩存一些用戶信息,有了localStorage
的功能,讓我們的應用能展示歷史消息。
消息通知的顯示用到了一個push.js
的庫,比較輕量,可以結合:animate.css
使用。
用戶認證模塊
本應用沒有登錄模塊,所以需要實現一個用戶認證模塊,來保證用戶篡改和唯一性,流程圖如下:
這里用到了2個庫,第一個是uuid
用來生成唯一的用戶id,第二個是jsonwebtoken
。用來生成加密token
,可以存儲用戶id,還可以用來校驗是否被篡改和過期。
用戶第一次打開的時候,服務端會返回分配的uuid
和token
。服務端會保存在本地,下次用戶連入的時候,會將uuid
和token
發給服務器做驗證,合法才讓用戶接入websocket
服務,否則會被強制斷開連接。
寫在最后
本文主要介紹websocket
實現一個簡單的聊天室功能,沒有接入數據庫,所以是沒法做持久化的,用戶聊天記錄和身份信息保存在用戶本地,通信過程也沒有加密,僅供參考。上面也提供了核心實現代碼,感興趣的小伙伴可以自己動手嘗試嘗試,該聊天小程序的功能會逐漸完善,可以持續關注。下期我會將這個簡單的引用使用electron
將該引用打包成一個桌面應用的安裝程序。
electron
可以使用 JavaScript
,HTML
和 CSS
構建跨平台的桌面應用程序。功能很強大,它相當於是將nodeJs
和網頁結合了,下次會做出具體介紹。
相關閱讀:
一文看懂websocket
聊天應用在線體驗