websocket實現一個聊天室

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

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

功能結構圖

UntitledDiagram.jpg
能夠看到,該聊天室主要分爲三個部分:消息實時推送,聊天界面與交互實現,用戶認證模塊。下面講講這個3個模塊的實現方式。前端

總體架構

前端:vue-cli搭建+websock客戶端vue

後端:nodeJs+websock服務端+JWT認證java

消息推送模塊實現

主要用到了websock的雙工通訊功能:
服務端核心代碼:node

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 來告訴客戶端收到消息的類型,分別是:web

1: 收到新消息
2: 收到在線用戶數量的通知
3: 收到用戶身份信息
4: 收到在線用戶列表

客戶端核心代碼:vue-cli

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,它們主要是:json

// 緩存全部用戶本地聊天記錄
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可使用 JavaScriptHTML CSS 構建跨平臺的桌面應用程序。功能很強大,它至關因而將nodeJs和網頁結合了,下次會作出具體介紹。

相關閱讀:

一文看懂websocket

聊天應用在線體驗

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

我的公衆號:長按保存關注

相關文章
相關標籤/搜索