在前端中 WebSocket 是H5新增的对象

主要作用有:实时通讯  长连接  双向传输  后端主动推送数据

websocket实例的主要事件

前端:

直接new 一个实例

const ws = new WebSocket("ws://localhost:9100");

大部分浏览器已经支持 WebSocket 对象  协议格式为ws(不是 file http)

主要事件:

open 建立链接
close 断开链接
error 发生错误
message 发送消息给后端

后端:

使用node 来简单搞一个 本地服务、后端要依赖第三方包使用websocket 这里以ws为例

npm i ws@8.10.0

引入ws 创建服务 配置端口和前端一致

const ws = require('ws')

const wss= new ws.Server({port:9100})

主要事件:

open 建立链接
close 断开链接
error 发生错误

connection

message

有客户端连接上

接收到客户端发送来的消息

一般 message事件在 connection里面

案例流程梳理

  1. 首先登录 选择 头像 起昵称(不能和聊天室内已经有的的重复)
  2. 进入聊天室 发送欢迎信息  显示在线人数+1
  3. 发消息时 后端会自动转发给其他连接上的客户端
  4. 退出的时候 释放 昵称的命名空间

登录页面展示:

样式部分省略...

使用双向绑定获取 用户输入的昵称和 选择的头像  头像v-for渲染数据  点击时currentIndex修改为当前的索引 根据索引 增加高亮边框和 选择此数据传给下一步

  <input type="text" placeholder="请输入发言昵称" v-model="nickname" id="input" /><ul class="avatar"><li v-for="(aa,index) in avatar_list":key="index":class="{curr : currentIndex===index}"@click="bianse(index)"><img :src="aa" alt=""></li>

验证输入用户的长度要在1-9位

想服务器发起请求 存放昵称(禁止其他人使用)

收集数据保存到  localStorage 中 进行下一步

  methods:{defind(){if (this.nickname.length < 1) {return alert("请输入昵称");}if (this.nickname.length > 9) {return alert("输入昵称过长");}this.$http.get(`/login/${this.nickname}`).then(res => {if(res.data.status === 1){localStorage.setItem("nickname", this.nickname);localStorage.setItem("avatar", this.avatar_list[this.currentIndex]);this.$router.push('/about')}else{return alert("昵称已被占用");}})},bianse(index){this.currentIndex = index}}

聊天室页面

预留组件中需要的数据  进入组件和挂载元素 生命周期中进行对应的操作

进入到页面 简易判断 前一步保存到 localStorage 的数据是否存在 如果不存在自动返回登录页面重新设置  防止用户跳过登录直接进入到 聊天室 没有昵称导致的一系列错误   这一步也可以使用 导航守卫来实现

  data(){return {nickname:'', // 用户的昵称message:'', // 用户发送的消息record:[], // 消息记录数组ws:null, // ws 实例 预留变量user_list:[] // 实时在线人数列表}},created() {this.nickname = localStorage.getItem("nickname")if (!this.nickname) {return this.$router.push('/');}},

mounted 生命周期中 创建 WebSocket实例

添加 ws相关事件 这里只需要

open 连接上ws服务器端了 发送欢迎消息

message 接收到服务器返回来的数据 渲染到页面 聊天信息部分 并判断是新进入的用户发送的消息 还是老用户发送的消息 如果是新用户 就添加到左侧在线列表 老用户此步骤忽略

业务流程:连接上后端发送欢迎消息 =》后端接收消息 返回给每个客户端  =》 客户端接收到服务端发来的消息 渲染到 消息列表 并且根据条件 渲染左侧在线列表

    mounted() {this.ws = new WebSocket("ws://localhost:9100");this.ws.addEventListener("open", () => {this.ws.send(JSON.stringify({user: this.nickname,avatar:localStorage.getItem('avatar'),dateTime: this.nowTimeFormatChinese(new Date()),message:'欢迎 ' +this.nickname + ' 来到聊天室',}));});this.ws.addEventListener("message", (e) => {const data = JSON.parse(e.data)this.record.push(data);const flag = this.user_list.filter(x => x.user === data.user)if(flag.length === 0){this.user_list.push(data);}});},

点击发送按钮  组织好数据 ws.send 发送给服务端

发送消息 返回渲染之后 滚动跳滚到最新消息处

this.$refs.lists.scrollTop += 100

// window.scrollTo(0, document.body.scrollHeight);

还有格式化时间的方法

    methods:{send(){if (!this.message.trim().length) {return alert("请输入内容");}this.ws.send(JSON.stringify({user: this.nickname,avatar:localStorage.getItem('avatar'),dateTime: this.nowTimeFormatChinese(new Date()),message: this.message,}));this.message = "";setTimeout(()=>{this.$refs.lists.scrollTop += 100// window.scrollTo(0, document.body.scrollHeight);},100)},padZero(n){return n > 9 ? n : "0" + n;},nowTimeFormatChinese(riqi){let hour = this.padZero(riqi.getHours()),min = this.padZero(riqi.getMinutes()),sec = this.padZero(riqi.getSeconds())return hour + "时" + min + "分" + sec + "杪";}},

离开页面(销毁组件)时 清楚自己的昵称 ---左侧的在线列表 和 服务器端的命名空间

    deactivated(){const index = this.user_list.findIndex(x => x.user === this.nickname)this.user_list.splice(index, 1)this.$http.get(`/loginout/${this.nickname}`)},

聊天室页面完整模板(样式省略):

渲染消息列表时 判断是不是自己所发的消息 返回来的user === 自己的nickname

是的话添加  meSay 样式  右侧显示 作为区分

<template><div class="about"><ul id="list" ref="lists"><li v-for="(n,index) in record" :key="index" :class="{meSay : n.user === nickname}">
<div><div class="cow"><img :src="n.avatar" alt="" class="avatar"><p class="ppp"><span>{{n.user}}</span><br><span>{{n.dateTime}}</span></p></div><div class="nei">{{n.message}}</div>
</div></li></ul><div class="bottom"><div class="people"><h3>当前在线人数:{{this.user_list.length}}</h3><div class="user_list" v-for="n in user_list" :key="n.user"><img :src="n.avatar" alt="">{{n.user}}</div></div><textarea id="message" v-model="message" @keyup.enter="send"></textarea><button id="send" @click="send">发送</button></div></div>
</template>

后端完整代码

ws部分比较简单  监听链接 和 接收消息的事件  出发了就遍历所有链接的客户端 把数据原封不动的发送出去

const ws = require('ws')const wss= new ws.Server({port:9100})wss.on('connection',(client)=>{   // clent 这个客户端链接了client.on('message',(msg)=>{    // 并且发来了数据const radio = msg.toString()  // 数据转换格式防止乱码wss.clients.forEach(e =>{     // 遍历再原封不动发送给每个链接的客户端e.send(radio)})})
})

管理昵称命名空间的端口

引入express 快速搭建本地服务器

npm i express@4

使用中间件 解决跨域问题

创建 activeUser 数组储存 已在线的用户昵称、登录时发送请求携带 nickname req.params 获取路径中的形参 判断在 activeUser 中是否存在 如果存在添加失败 不存在 添加进去 这样保证昵称不重复、 注销时发送请求 携带nickname 在activeUser 查找到 并且 删除它

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()// 这样也可以解决跨域问题
app.use(function(req,res,next){// 第二个 * 代表通配符  也可以指定具体的网站 http://www.wsg3096.comconst  contentType = 'application/json; charset=utf-8'res.setHeader('Content-Type',contentType)res.setHeader('Access-Control-Allow-Origin','*')// 后面的也可以用通配符res.setHeader('Access-Control-Allow-Methods','OPTIONS,GET,PUT,POST,DELETE')// 设置其他的请求头res.setHeader('Access-Control-Allow-Headers','Content-Type','X-Custom-Header')next()
})const activeUser = []// 登录的 API 接口
app.get('/api/login/:nickname', (req, res) => {const nickname = req.params.nicknameconst find = activeUser.find(x => x=== nickname)if(find){return res.send({status:0,msg:'用户昵称已经被占用'})}else{activeUser.push(nickname)return res.send({activeUser,status:1,msg:'成功进入聊天室队列'})}
})// 注销的接口
app.get('/api/loginout/:nickname', (req, res) => {const nickname = req.params.nicknameconst index = activeUser.findIndex(x => x=== nickname)activeUser.splice(index,1)return res.send({activeUser,status:200,msg: `成功释放${nickname}的命名空间`})
})// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(7777, function () {console.log('Express server running at http://127.0.0.1:7777')
})

Vue+WebSocket-实现多人聊天室相关推荐

  1. SpringBoot WebSocket之多人聊天室实现

    SpringBoot WebSocket之多人聊天室实现 WebSocket简介 什么是WebSocket? 为什么使用WebSocket? WebSocket的技术特点: WebSocket的技术优 ...

  2. Nodejs+webSocket搭建多人聊天室

    NodeJs+webSocket搭建多人聊天室 准备的东西: 第一步:安装插件并且完善服务端 第二步 :搭建客户端并与服务端的通信 第三步 :添加CSS样式 第四步:总结 今天花了一个上午的时间去学习 ...

  3. 基于SpringBoot的websocket的多人聊天室项目

    文章目录 1.websocket 什么是websocket? 使用步骤 1.引入依赖 2.建立配置类 3.业务层 Web类 HTML 遇到的问题 项目github地址 1.websocket 什么是w ...

  4. JAVA利用websocket实现多人聊天室、私信(附源码)

    声明:此文为原创,转载请声明出处! 小编曾在毕业设计中用到了聊天室这个功能,现在稍作整理分享一下,希望能对大家有所帮助,有不足之处请指出 在学习websocket前,首先得知道它的一些基本操作,可参考 ...

  5. 基于 Vue 开发一个 多人聊天室(万字长文) - 从 0 到 1 篇

    前言 在上个月初,接到一个需求,要开发一个 聊天通讯 模块 并且 集成到 项目中的多个 入口,实现业务数据的记录追踪. 接到需求后,还挺开心,这是我第一次 搞 通讯 类的需求,之前一直是 B 端 的业 ...

  6. websocket多人聊天php,php-notes/基于websocket实现多人聊天室.md at master · dd-code-site/php-notes · GitHub...

    WebSocket 连接 断开 格式:ws://IP或域名:端口 发送 消息 var websocket; var wsUrl; function connect() { try { wsUrl = ...

  7. socket.io php 聊天室,WebSocket学习(一)——基于socket.io实现简单多人聊天室

    前言 什么是Websocket呢? 我们都知道在Http协议中,客户端与服务器端的通信是靠客户端发起请求,然后服务器端收到请求再进行回应,这个过程中,客户端是主动的,服务器端是被动的.Websocke ...

  8. WebSocket实现简易版的多人聊天室

    一.websocket简介           WebSocket是一种在单个TCP连接上进行全双工通信的协议.WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推 ...

  9. SpringBoot——SpringBoot集成WebSocket实现简单的多人聊天室

    文章目录: 1.什么是WebSocket? 2.Java中的WebSocket API 2.1 WebSocket开发中的相关注解及API方法 2.2 前端技术对WebSocket的支持 3.多人聊天 ...

最新文章

  1. Python_note8 程序设计方法学+Python第三方库安装+os库
  2. Struts Web应用程序开发步骤
  3. 【lora无线数传通信模块】亿佰特E22串口模块用于物联网地震预警传感通信方案
  4. [Linux]CRC校验
  5. 信息学奥赛C++语言:最小数输出
  6. 我喜欢阅读和计算机英语,关于自考中的计算机专业
  7. java ssm框架 mapper文件里的#符号和$符号的区别
  8. 阿里重启维护Dubbo了
  9. 设计模式之单例模式8种实现方式,其七:静态内部类
  10. 从shell命令行推送数据到远程MySQL数据库
  11. MySQL-(1)查看用户权限、(2)用户授权、(3)删除用户权限 语法格式总结
  12. IntelliLock
  13. 国二java好过还是office好过,计算机二级考哪一个科目比较容易过,Ms office 较为简单实用...
  14. matlab驻波仿真
  15. 项目1在线交流平台-7.构建安全高效的企业服务-5.redis高级数据结构应用-统计网站数据-独立访客和日活跃用户
  16. social域名是什么样的域名?有什么注册规则?
  17. linux字符驱动愚见
  18. linux操作系统安装容易出的问题,[操作系统]装Linux出问题了,请大家帮帮忙~~!
  19. 假如工资有段位,你是个啥?
  20. NFV与SDN的区别与联系

热门文章

  1. 整体功能大于部分功能之和_功能性思考,第1部分
  2. 数据挖掘实战分享:财政收入影响因素分析及预测(四)
  3. 程序设计六大原则-概况与举例
  4. IMX6 EMMC、SD卡启动引脚配置及uboot修改为SD2启动
  5. 调节e18-d80nk的测量距离_超声波液位计的测量方法及其在水位监测中的应用
  6. HCIE Datacom认证学什么内容
  7. 根据udev机制创建video camera设备节点软链接
  8. IEEE 1394 接口的ESD静电保护模块方案
  9. 智慧电力大屏可视化决策系统
  10. 搭建SRS服务器(一)