0


【node进阶】深入浅出websocket即时通讯(二)-实现简易的群聊&私聊

✅ 作者简介:一名普通本科大三的学生,致力于提高前端开发能力
✨ 个人主页:前端小白在前进的主页
🔥 系列专栏 : node.js学习专栏
⭐️ 个人社区 : 个人交流社区
🍀 学习格言: ☀️ 打不倒你的会使你更强!☀️
💯 刷题网站:这段时间有许多的小伙伴在问有没有什么好的刷题网站,博主在这里给大家推荐一款刷题网站:👉点击访问牛客网👈牛客网支持多种编程语言的学习,各大互联网大厂面试真题,从基础到拔高,快来体验一下吧!


在这里插入图片描述


🔥前言

相信在上一篇的文章中大家对websocket的基本轮廓包括基础知识做了一定的了解学习,那么本篇文章将会从demo的角度去实现

群聊

私聊

的功能,一起来看看吧!

📃目录

实现效果

在这里插入图片描述
这里有个小遗憾,我忘给私聊添加一个简单的样式了,这也是最后我突然发现了,xdm,你们在下面可以去添加一下私聊的简单dom,我这里就用控制台打印实现了!


前台核心代码


设置不同状态

在这里设置了四种状态,每种状态对应着相应的功能,有

获取群列表信息

转到群聊

转到私聊
const WebSocketType ={Error:0,//错误GroupList:1,//群列表GroupChat:2,//群聊SingleChat:3//私聊}

封装一个发送信息函数

因为我们给后端发送信息时只能传

字符串

,所以我们将传给后端的这个对象转换成字符串的形式,使用内置方法

JSON.stringify()
functioncreateMessage(type, data, to){returnJSON.stringify({
        type,
        data,
        to
    });}

后台核心代码

获取到token

使用js中的内置方法

new URL()

获取到请求地址的参数,注意,这里的

req.url

是请求地址后面的参数!

const myURL =newURL(req.url,"http://127.0.0.1:3000")const token = myURL.searchParams.get("token")

封装一个给前端返回消息的函数

与前台的代码相似,给前台对应的状态返回信息!

functioncreateMessage(type, user, data){returnJSON.stringify({type: type,user: user,data: data
    });}

定义与前端一致的状态对象

实现与前台对象相对应的状态!

const WebSocketType ={Error:0,//错误GroupList:1,//群列表GroupChat:2,//群聊SingleChat:3//私聊}

封装一个js文件处理token

const jwt =require('jsonwebtoken')const secret ='ccc-data'constJWT={//jwt的sign()生成tokengenerate(value,expires){return jwt.sign(value,secret,{expiresIn:expires})},//解密token,验证verify(token){try{return jwt.verify(token,secret)}catch(error){returnfalse}}}

module.exports =JWT

校验token

这里校验token,成功后,就会给前台返回

欢迎来到本聊天室

的字样,并且给我们的

句柄

添加一个user属性,目的是让我们明确是谁进入到了聊天室,返回进入聊天室这个人的信息!

// 校验tokenconst payload =JWT.verify(token)if(payload){
        ws.send(createMessage(WebSocketType.GroupChat,null,'欢迎来到本聊天室'));
        ws.user = payload
        //群发sendAll()}else{
        ws.send(createMessage(WebSocketType.Error,null,'token过期'))}

前台实现(所有代码)

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="./stylesheets/chat.css"></head><body><h1 id="h1">欢迎来到聊天室</h1><h3 id="h3"></h3><input type="text" id="text"><button id="send">send</button><select id="select"></select><div id="chat"></div><!-- 建立socket连接,带着token,后端验证 --><script>
        h1.innerHTML =`${localStorage.getItem("username")}欢迎您来到聊天室`const WebSocketType ={Error:0,//错误GroupList:1,//群列表GroupChat:2,//群聊SingleChat:3//私聊}functioncreateMessage(type, data, to){returnJSON.stringify({
                type,
                data,
                to
            });}const ws =newWebSocket(`ws://localhost:8080?token=${localStorage.getItem("token")}`)
        ws.onopen=()=>{
            console.log('连接成功!');}
        ws.onmessage=(msgObj)=>{// console.log(msgObj.data);
            msgObj =JSON.parse(msgObj.data)switch(msgObj.type){case WebSocketType.Error:
                    localStorage.removeItem("token")
                    location.href ='/login'break;case WebSocketType.GroupList:
                    console.log(JSON.parse(msgObj.data));const onlineList =JSON.parse(msgObj.data)
                    h3.innerHTML =``
                    h3.innerHTML =`当前在线人数:${onlineList.length}`
                    select.innerHTML =``
                    select.innerHTML =`<option value="all">All</option>`+ onlineList.map(item=>`
                        <option value="${item.username}">${item.username}</option>
                    `).join('')break;case WebSocketType.GroupChat:
                    console.log((msgObj.user ? msgObj.user.username :'广播')+':'+ msgObj.data);var para = document.createElement("p");var node = document.createTextNode((msgObj.user ? msgObj.user.username :'广播')+':'+ msgObj.data);
                    para.appendChild(node);
                    chat.appendChild(para);break;case WebSocketType.SingleChat:
                    console.log(msgObj.user.username +':'+ msgObj.data);break;}}
        send.onclick=()=>{if(select.value ==='all'){// console.log('群发');
                ws.send(createMessage(WebSocketType.GroupChat, text.value))}else{// console.log('私聊');
                ws.send(createMessage(WebSocketType.SingleChat, text.value, select.value))}}</script></body></html>

node后台实现(所有代码)

//websocket响应const{ json }=require('express');const WebSocket =require('ws');constJWT=require('../util/jwt');const WebSocketServer = WebSocket.WebSocketServer
const wss =newWebSocketServer({port:8080});

wss.on('connection',functionconnection(ws, req){const myURL =newURL(req.url,"http://127.0.0.1:3000")
    console.log(req.url);//获取到token,随后进行验证const token = myURL.searchParams.get("token")// 校验tokenconst payload =JWT.verify(token)
    console.log(payload);if(payload){
        ws.send(createMessage(WebSocketType.GroupChat,null,'欢迎来到本聊天室'));
        ws.user = payload
        //群发sendAll()}else{
        ws.send(createMessage(WebSocketType.Error,null,'token过期'))}
    ws.on('message',functionmessage(data){
        console.log('received: %s', data);const msgObj =JSON.parse(data)//解析前台传来的数据switch(msgObj.type){//通过switch分支来进行不同状态的相应操作case WebSocketType.GroupList://获取进入聊天室的人员列表
                ws.send(createMessage(WebSocketType.GroupList,null,JSON.stringify(Array.from(wss.clients).map(item=> item.user))))//由于返回的类型是set集合,所以我们通过Array.from()转化为真正的数组!break;case WebSocketType.GroupChat://群聊分支//转发给其他人
                wss.clients.forEach(functioneach(client){if(client.readyState === WebSocket.OPEN){
                        client.send(createMessage(WebSocketType.GroupChat, ws.user,msgObj.data),{binary:false})}});break;case WebSocketType.SingleChat://私聊分支
                wss.clients.forEach(functioneach(client){// console.log(client.user);
                    console.log(ws.user);if(client.user.username === msgObj.to && client.readyState === WebSocket.OPEN){
                        client.send(createMessage(WebSocketType.SingleChat, ws.user,msgObj.data),{binary:false})}});break;}});
    ws.on('close',()=>{
        wss.clients.delete(ws.user)sendAll()})});const WebSocketType ={Error:0,//错误GroupList:1,//群列表GroupChat:2,//群聊SingleChat:3//私聊}functioncreateMessage(type, user, data){returnJSON.stringify({type: type,user: user,data: data
    });}constsendAll=()=>{//转发给其他人
    wss.clients.forEach(functioneach(client){if(client.readyState === WebSocket.OPEN){
            client.send(createMessage(WebSocketType.GroupList,null,JSON.stringify(Array.from(wss.clients).map(item=> item.user))))}});}

小结

这些代码看起来觉得好多好多呀,其实我们滤清思路分析一下,可以发现前后端是对应着的,按着对应关系一一去写代码就会非常轻松,这里的代码逻辑相对来说还是很清晰的,本篇文章到这里就结束了!下周开始不定时要进行

js的重生之路了

,将会结合许许多多的demo带领大家去学习js,不至于到头来啥也不会,少年,继续加油吧!

注意

登录

功能的设置token,以及axios的拦截器将会在以后的node项目实战中与大家见面,我们之前学了jwt,相信大家会写一个登录的接口和简单页面!


👑书写不易,希望大家能够给予三连支持,期待我更好的文章哟👑


在这里插入图片描述


本文转载自: https://blog.csdn.net/m0_52040370/article/details/127854142
版权归原作者 前端小白在前进 所有, 如有侵权,请联系我们删除。

“【node进阶】深入浅出websocket即时通讯(二)-实现简易的群聊&私聊”的评论:

还没有评论