WebSocket 实现简单聊天功能
利用WebSocket长连接实现即使通讯,可以实现个人单独聊天,内容不需要存服务器,这里只有前端代码,后端负责传递消息和用户列表。
<template><div><div class="content" style="display: flex;"><div class="leftChat"><div v-for="(item,index) in peopleList" :key="index" @click="userchange(item,index)":class="indexChekck == index ? 'peopelCheck' : 'people'"><img :src=" item.avatar ? baseUrl + item.avatar : require('@/assets/image/profile.png')" alt=""style="width: 50px;height: 50px;"> <span style="width: 60px;font-size: 16px;">{{item.userName}}</span><div class="xaioxi" v-if="item.number >0">{{ item.number >=99 ? '99+' : item.number+ '+' }}</div></div><div v-if="peopleList.length ==0">暂无人在线</div></div><div v-if="showPeo" style="position: relative;"><div class="top"><img :src=" topeople.avatar ? baseUrl + topeople.avatar : require('@/assets/image/profile.png')"alt="" style="width: 50px;height: 50px;border-radius: 50%;margin-left: 5px;"><span style="margin-left: 10px;">{{topeople.userName}}</span></div><!-- 聊天内容 --><div id="message" style="" ref="message"><div v-for="(item,idnexs) in this.allPeople[this.chatIndex].chatList" :key="idnexs"style="position: relative;"><div class="left" v-if="item.class =='left'"><div style="text-align: left;font-size: 14px;">{{item.name }}</div><div style="margin: 10px 0;text-align: left;"><!-- <div class="leftText">{{ item.message }}</div><img :src="baseUrl + item.img" alt=""> --><div v-html="item.message" class="leftText"></div></div></div><div class="right" v-if="item.class =='right'"><div style="text-align: right;font-size: 14px;">{{item.name }}</div><div style="margin: 10px 0;text-align: right;"><!-- <div class="rightText">{{ item.message }}</div> --><div v-html="item.message" class="rightText"></div></div></div></div></div><div id="text" class="editable-container" :contenteditable="true" @keydown="textareaKeydown($event)"></div><!-- <div id="text"></div><el-input text="text" id="text" @keydown="textareaKeydown($event)" :v-model="messages"></el-input> --><div @click="sendMessage" class="sendBtn">发送消息</div></div></div></div>
</template>
这是简单界面,实现简单聊天,只能和在线的人聊天,无法和不在线的聊天,
getIs() {let that = this//判断当前浏览器是否支持WebSocketif ('WebSocket' in window) {websocket = new WebSocket("ws://自己的地址" );} else {alert('Not support websocket');}//接收到消息的回调方法websocket.onmessage = function (event) {that.showMessage(event.data);let data = JSON.stringify(event.data);if (data.dataType == 3) {alert(data.message);}}},showMessage(message) {let data = JSON.parse(message);let messages = ''if (data.dataType == 1) {let arr = []if (this.allPeople.length != 0) {arr = this.peopleList}this.peopleList = data.userListthis.peopleList.forEach(item => {for (let i = 0; i < arr.length; i++) {if (item.userId == arr[i].userId) {item.number = arr[i].number ? arr[i].number : 0}}})let array = data.userListif (this.allPeople.length != 0) {this.allPeople.forEach((item) => {for (let i = 0; i < array.length; i++) {let n = 0let m = 0if (item.id != array[i].userId) {n++} else {m++}if (n >= array.length) {this.allPeople.push({id: array[i].userId,chatList: [],number: 0,isTrue: true})}if (m >= 1) {item.isTrue = true} else {item.isTrue = false}}})} else {for (let i = 0; i < array.length; i++) {this.allPeople.push({id: array[i].userId,chatList: [],number: 0,isTrue: true})}}// console.log('所有列表', this.allPeople);} else if (data.dataType == 2) {messages = data.messagethis.allPeople.forEach((item, index) => {if (item.id == data.fromUserId) {this.allPeople[index].chatList.push({class: 'left',message: data.message,name: data.fromUserName,// img: '/profile/signature/2021/12/09/64c9f089-b0fb-4a3f-a51b-8240369a09d6.jpeg',})}})this.peopleList.forEach(item => {if (item.userId == data.fromUserId && data.fromUserId != this.toUserId) {item.number++}})this.$forceUpdate()// console.log('人员信息', this.peopleList);this.$emit('newchatChange')// console.log('dsadsad', this.allPeople[this.chatIndex]);this.$nextTick(() => {let ele = document.getElementById("message");//判断元素是否出现了滚动条if (ele) {ele.scrollTop = ele.scrollHeight;}//设置滚动条到最底部})} else if (data.dataType == 4) {this.$message('对方已掉线,您发送的消息对方已经看不到了')}// console.log('data', data, this.peopleList);// document.getElementById('messages').innerHTML += messages + '<br/>';},userchange(val, index) {this.indexChekck = indexthis.showPeo = truethis.topeople = valthis.toUserId = val.userId// console.log('点击了', val);this.allPeople.forEach((item, index) => {if (item.id == this.toUserId) {this.chatIndex = indexthis.allPeople[this.chatIndex].number = 0}})this.peopleList.forEach(item => {if (item.userId == this.toUserId) {item.number = 0}})this.$nextTick(() => {let ele = document.getElementById("message");//判断元素是否出现了滚动条if (ele) {ele.scrollTop = ele.scrollHeight;}//设置滚动条到最底部})// console.log('dsadsadasdsad', this.allPeople[this.chatIndex]);},//监听按键操作textareaKeydown(event) {if (event.ctrlKey && event.keyCode === 13) {event.preventDefault() // 阻止浏览器默认换行操作} else if (event.keyCode === 13) {//enterthis.sendMessage();event.preventDefault() // 阻止浏览器默认换行操作return false}},//发送消息sendMessage() {// if (websocket) {// // websocket.close();// } else {// this.getIs()// }var msgBak = document.getElementById('text').innerHTML;if (msgBak != null && msgBak != "") {// console.log('消息列表', this.chatList);let data = {toUserId: this.toUserId,message: msgBak}var map2json = JSON.stringify(data)if (map2json.length < 8000) {websocket.send(map2json);document.getElementById('text').innerHTML = null;this.allPeople[this.chatIndex].chatList.push({class: 'right',message: msgBak,name: localStorage.getItem('nickName')})// console.log('发送消息', this.allPeople);this.$nextTick(() => {let ele = document.getElementById("message");//判断元素是否出现了滚动条//设置滚动条到最底部ele.scrollTop = ele.scrollHeight;})} else {this.$message('文本或者图片太长了,少写一点吧')document.getElementById('text').innerHTML = null;}} else {this.$message('请输入内容')}this.messages = null},
js部分实现用户列表查询,发送消息,以及接收消息,有消息会提示,
一下是全部代码
<template><div><!-- <div id="messages"></div> --><div class="content" style="display: flex;"><div class="leftChat"><div v-for="(item,index) in peopleList" :key="index" @click="userchange(item,index)":class="indexChekck == index ? 'peopelCheck' : 'people'"><img :src=" item.avatar ? baseUrl + item.avatar : require('@/assets/image/profile.png')" alt=""style="width: 50px;height: 50px;"> <span style="width: 60px;font-size: 16px;">{{item.userName}}</span><div class="xaioxi" v-if="item.number >0">{{ item.number >=99 ? '99+' : item.number+ '+' }}</div></div><div v-if="peopleList.length ==0">暂无人在线</div></div><div v-if="showPeo" style="position: relative;"><div class="top"><img :src=" topeople.avatar ? baseUrl + topeople.avatar : require('@/assets/image/profile.png')"alt="" style="width: 50px;height: 50px;border-radius: 50%;margin-left: 5px;"><span style="margin-left: 10px;">{{topeople.userName}}</span></div><!-- 聊天内容 --><div id="message" style="" ref="message"><div v-for="(item,idnexs) in this.allPeople[this.chatIndex].chatList" :key="idnexs"style="position: relative;"><div class="left" v-if="item.class =='left'"><div style="text-align: left;font-size: 14px;">{{item.name }}</div><div style="margin: 10px 0;text-align: left;"><!-- <div class="leftText">{{ item.message }}</div><img :src="baseUrl + item.img" alt=""> --><div v-html="item.message" class="leftText"></div></div></div><div class="right" v-if="item.class =='right'"><div style="text-align: right;font-size: 14px;">{{item.name }}</div><div style="margin: 10px 0;text-align: right;"><!-- <div class="rightText">{{ item.message }}</div> --><div v-html="item.message" class="rightText"></div></div></div></div></div><div id="text" class="editable-container" :contenteditable="true" @keydown="textareaKeydown($event)"></div><!-- <div id="text"></div><el-input text="text" id="text" @keydown="textareaKeydown($event)" :v-model="messages"></el-input> --><div @click="sendMessage" class="sendBtn">发送消息</div></div></div></div>
</template>
<!-- <script src="./"></script> -->
<script>let websocket = null;export default {data() {return {messagesss: null,chatIndex: -1,allPeople: [], //所有人的消息indexChekck: -1,chatList: [],showPeo: false,topeople: {},toUserId: null,baseUrl: process.env.VUE_APP_BASE_API,peopleList: [],messages: null,id: localStorage.getItem('userId'),shakeList: [],}},mounted() {let time = nulltime = setInterval(() => {if (websocket) {websocket.close();this.getIs()} else {this.getIs()}}, 30000);this.getIs()},methods: {getIs() {let that = this//判断当前浏览器是否支持WebSocketif ('WebSocket' in window) {websocket = new WebSocket("ws://自己的地址" + this.id);} else {alert('Not support websocket');}//接收到消息的回调方法websocket.onmessage = function (event) {that.showMessage(event.data);let data = JSON.stringify(event.data);if (data.dataType == 3) {alert(data.message);}}},showMessage(message) {let data = JSON.parse(message);let messages = ''if (data.dataType == 1) {let arr = []if (this.allPeople.length != 0) {arr = this.peopleList}this.peopleList = data.userListthis.peopleList.forEach(item => {for (let i = 0; i < arr.length; i++) {if (item.userId == arr[i].userId) {item.number = arr[i].number ? arr[i].number : 0}}})let array = data.userListif (this.allPeople.length != 0) {this.allPeople.forEach((item) => {for (let i = 0; i < array.length; i++) {let n = 0let m = 0if (item.id != array[i].userId) {n++} else {m++}if (n >= array.length) {this.allPeople.push({id: array[i].userId,chatList: [],number: 0,isTrue: true})}if (m >= 1) {item.isTrue = true} else {item.isTrue = false}}})} else {for (let i = 0; i < array.length; i++) {this.allPeople.push({id: array[i].userId,chatList: [],number: 0,isTrue: true})}}// console.log('所有列表', this.allPeople);} else if (data.dataType == 2) {messages = data.messagethis.allPeople.forEach((item, index) => {if (item.id == data.fromUserId) {this.allPeople[index].chatList.push({class: 'left',message: data.message,name: data.fromUserName,// img: '/profile/signature/2021/12/09/64c9f089-b0fb-4a3f-a51b-8240369a09d6.jpeg',})}})this.peopleList.forEach(item => {if (item.userId == data.fromUserId && data.fromUserId != this.toUserId) {item.number++}})this.$forceUpdate()// console.log('人员信息', this.peopleList);this.$emit('newchatChange')// console.log('dsadsad', this.allPeople[this.chatIndex]);this.$nextTick(() => {let ele = document.getElementById("message");//判断元素是否出现了滚动条if (ele) {ele.scrollTop = ele.scrollHeight;}//设置滚动条到最底部})} else if (data.dataType == 4) {this.$message('对方已掉线,您发送的消息对方已经看不到了')}// console.log('data', data, this.peopleList);// document.getElementById('messages').innerHTML += messages + '<br/>';},userchange(val, index) {this.indexChekck = indexthis.showPeo = truethis.topeople = valthis.toUserId = val.userId// console.log('点击了', val);this.allPeople.forEach((item, index) => {if (item.id == this.toUserId) {this.chatIndex = indexthis.allPeople[this.chatIndex].number = 0}})this.peopleList.forEach(item => {if (item.userId == this.toUserId) {item.number = 0}})this.$nextTick(() => {let ele = document.getElementById("message");//判断元素是否出现了滚动条if (ele) {ele.scrollTop = ele.scrollHeight;}//设置滚动条到最底部})// console.log('dsadsadasdsad', this.allPeople[this.chatIndex]);},//监听按键操作textareaKeydown(event) {if (event.ctrlKey && event.keyCode === 13) {event.preventDefault() // 阻止浏览器默认换行操作} else if (event.keyCode === 13) {//enterthis.sendMessage();event.preventDefault() // 阻止浏览器默认换行操作return false}},//发送消息sendMessage() {// if (websocket) {// // websocket.close();// } else {// this.getIs()// }var msgBak = document.getElementById('text').innerHTML;if (msgBak != null && msgBak != "") {// console.log('消息列表', this.chatList);let data = {toUserId: this.toUserId,message: msgBak}var map2json = JSON.stringify(data)if (map2json.length < 8000) {websocket.send(map2json);document.getElementById('text').innerHTML = null;this.allPeople[this.chatIndex].chatList.push({class: 'right',message: msgBak,name: localStorage.getItem('nickName')})// console.log('发送消息', this.allPeople);this.$nextTick(() => {let ele = document.getElementById("message");//判断元素是否出现了滚动条//设置滚动条到最底部ele.scrollTop = ele.scrollHeight;})} else {this.$message('文本或者图片太长了,少写一点吧')document.getElementById('text').innerHTML = null;}} else {this.$message('请输入内容')}this.messages = null},}}</script><style lang="scss">.editable-container {img {max-width: 190px !important;max-height: auto !important;}}.leftText img {max-width: 190px !important;max-height: auto !important;}.rightText img {max-width: 190px !important;max-height: auto !important;}</style>
<style lang="scss" scoped>.top {display: flex;align-items: center;border-bottom: rgb(167, 162, 162) 1px solid;height: 60px;line-height: 60px;width: 500px;background: #f5f5f5;}.content {position: fixed;// position: absolute;top: 100px;right: 60px;z-index: 999;}#message {padding: 10px;overflow: hidden;overflow: scroll;width: 500px;background: #f5f5f5;height: 400px;}.sendBtn {font-size: 14px;color: #07c160;border-radius: 5px;position: absolute;right: 20px;bottom: 10px;height: 30px;line-height: 30px;padding: 0 10px 0 10px;text-align: center;background: white;}.sendBtn:hover {background: #cecbcb;}#text {padding: 10px;border-top: 1px rgb(167, 162, 162) solid;background: #f5f5f5;width: 500px;height: 140px;overflow: hidden;overflow: scroll;img {width: 70px !important;height: 70px !important;}}#text::-webkit-scrollbar {display: none}.leftChat {min-width: 100px;padding: 10px;background: #e6e6e6;border-right: 1px rgb(167, 162, 162) solid;overflow: hidden;overflow: scroll;height: 600px;.xaioxi {position: absolute;top: 0px;right: 10px;width: 25px;height: 15px;border-radius: 10px;background: red;color: white;font-size: 12px;line-height: 15px;text-align: center;}// /deep/ .el-badge__content,// .el-badge__content--undefined,// .is-fixed {// top: 5px;// right: 35px;// }.people {position: relative;border-bottom: 1px solid rgb(167, 162, 162);margin-top: 10px;padding-bottom: 5px;display: flex;align-items: center;span {margin-left: 10px;}}.peopelCheck {position: relative;border-bottom: 1px solid rgb(167, 162, 162);margin-top: 10px;padding-bottom: 5px;display: flex;align-items: center;background: #cac8c6;span {margin-left: 10px;}}}// 去除滚动条显示#message::-webkit-scrollbar {display: none}// 去除滚动条显示.leftChat::-webkit-scrollbar {display: none}.left {// width: 100%;// float: left;margin-top: 20px;margin-right: 0px;}.right {// width: 100%;margin-top: 20px;// float: right;margin-right: 0px;}.rightText {margin-right: 0;line-height: 1.5;padding: 10px 20px;border-radius: 15px;color: #f7f8f8;background-color: #00a5ff;width: auto;max-width: 80%;display: inline-block;text-align: start;// width: 100%;line-height: 25px;white-space: normal;word-break: break-all;word-wrap: break-word;// min-width: 200px;// min-height: 200px;img {width: 150px !important;height: 150px !important;}}.leftText {white-space: normal;word-break: break-all;word-wrap: break-word;margin-left: 0px;line-height: 1.5;padding: 10px 20px;border-radius: 15px;color: black;background-color: #ffffff;width: auto;max-width: 80%;display: inline-block;}</style>
WebSocket 实现简单聊天功能相关推荐
- WebSocket实现简单聊天功能案例
简介 1.使用WebSocket实现的一个简单的聊天功能业务 2.使用了SpringBoot的ApplicationEvent事件监听用来与业务解耦 3.需要注意的是websocket的长连接默认会在 ...
- SpringBoot +WebSocket实现简单聊天室功能实例
SpringBoot +WebSocket实现简单聊天室功能实例) 一.代码来源 二.依赖下载 三.数据库准备(sql) 数据库建表并插入sql 四.resources文件配置 application ...
- 【SpringBoot框架篇】18.使用Netty加websocket实现在线聊天功能
文章目录 1.简介 2.最终功能实现的效果图 2.1.pc端 2.2.移动端 3.实战应用 3.1.引入依赖 3.2.配置文件 3.3.测试demo 3.3.1.消息内容实体类 3.3.2.处理请求的 ...
- php聊天功能_php实现简单聊天功能
搜索热词 1.创建聊天消息表,其表的字段有消息内容,发送时间和发送者的名称: CREATE TABLE `guanhui`.`message` ( `id` INT(10) NOT NULL AUTO ...
- JavaWeb--使用Websocket实现在线聊天功能
首先简单介绍下WebSocket,WebSocket是HTML5中内容,是基于TCP的一种新的网络协议,它支持全双工.长连接的通信.在它出现之前,实时消息发送与接收通过轮询实现,但是频繁与服务器建立连 ...
- 微信小程序 | 基于小程序+Java+WebSocket实现实时聊天功能
一.文章前言 此文主要实现在小程序内聊天对话功能,使用Java作为后端语言进行支持,界面友好,开发简单. 二.开发流程及工具准备 2.1.注册微信公众平台账号. 2.2.下载安装IntelliJ ID ...
- Ratchet实现PHP WebSocket多人聊天功能的示例
composer 安装ratchet composer require cboden/ratchet 使用PDO连接数据库,创建mysql命令如下 CREATE TABLE messages (id ...
- 保姆级别 附带源码 Django集成channels(一)实现简单聊天功能
目录 前言 不想看我瞎BB可以直接跳到这里 1.WebSocket 1.1 ajax轮询 1.2 long poll 1.3 Websocket 2.Channels 2.1 WSGI 2.2 ASG ...
- JSP使用Websocket技术实现聊天功能--H5网页前端部分(二)
[注]:使用的是LayUI作为前端框架,实现网页聊天功能,部分包可能出现版本更迭无法使用 前端页面 <%--Created by IntelliJ IDEA.User: ZhuDiDate: 2 ...
最新文章
- 2016总结 - 我的转型之路
- 解决[warn] _default_ VirtualHost overlap on port 80, the first has precedence问题
- jQuery 对象及伪数组
- kotlin学习之集合(十三)
- ML.NET Cookbook:(16)什么是规范化?为什么我需要关心?
- asp点击增加一条表格数据_asp生成excel报表(一)
- oracle 10g rac 停止,Oracle10g RAC 关闭及启动
- SpringMVC 注解 @Scope、@PostConstruct、@PreDestroy、@ComponentScan
- java 设置系统参数_Java 设置系统参数和运行参数
- Oracle函数写法和举例
- yolo系列外文翻译_yolov3论文中英对照版
- 计算机成绩统计优秀率,(完整word版)在excel中如何计算及格率和优秀率及统计各分数段人数...
- Android实现本地图片、视频左右镜像翻转
- python battleship_一个python初学者的作业,battleship
- [Scala基础]--Either介绍
- Unity 粒子系统参数一
- 【NLP技术】:NLP简单介绍
- Grunt搭建自动化web前端开发环境--完整流程
- 抗真菌、细菌化合物库、抑制剂
- 游戏地图和星际争霸地图技术