websocket實現一個聊天室

上次講了websoket的基礎知識和應用插件,今天我們來用websocket來實現一個聊天程序。先看幾張界面截圖:

聊天界面:
5.png
歷史消息查看:
6.png
用戶上線提醒:
7.png
在線體驗地址:地址

功能結構圖

UntitledDiagram.jpg
可以看到,該聊天室主要分爲三個部分:消息實時推送,聊天界面與交互實現,用戶認證模塊。下面講講這個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使用。

用戶認證模塊

本應用沒有登錄模塊,所以需要實現一個用戶認證模塊,來保證用戶篡改和唯一性,流程圖如下:
9.jpg
這裏用到了2個庫,第一個是uuid用來生成唯一的用戶id,第二個是jsonwebtoken。用來生成加密token,可以存儲用戶id,還可以用來校驗是否被篡改和過期。
用戶第一次打開的時候,服務端會返回分配的uuidtoken。服務端會保存在本地,下次用戶連入的時候,會將uuidtoken發給服務器做驗證,合法才讓用戶接入websocket服務,否則會被強制斷開連接。

寫在最後

本文主要介紹websocket實現一個簡單的聊天室功能,沒有接入數據庫,所以是沒法做持久化的,用戶聊天記錄和身份信息保存在用戶本地,通信過程也沒有加密,僅供參考。上面也提供了核心實現代碼,感興趣的小夥伴可以自己動手嘗試嘗試,該聊天小程序的功能會逐漸完善,可以持續關注。下期我會將這個簡單的引用使用electron將該引用打包成一個桌面應用的安裝程序。
electron可以使用JavaScriptHTMLCSS 構建跨平臺的桌面應用程序。功能很強大,它相當於是將nodeJs和網頁結合了,下次會做出具體介紹。

相關閱讀:

一文看懂websocket

聊天應用在線體驗

學習如逆水行舟,不進則退,前端技術飛速發展,如果每天不堅持學習,就會跟不上,我會陪着大家,每天堅持推送博文,跟大家一同進步,希望大家能關注我,第一時間收到最新文章。

個人公衆號:長按保存關注

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章