聊天广场(Vue+WebSocket+SpringBoot)

由于心血来潮想要做个聊天室项目 ,但是仔细找了一下相关教程,却发现这么多的WebSocket教程里面,很多都没有介绍详细,代码都有所残缺,所以这次带来一个比较完整得使用WebSocket的项目。

目录

一、效果展示

二、准备工作

一、前端框架,Vue + elementUI组件 +JsCookie

二、后端 SpringBoot + websocket包

三、前端代码

四、后端代码


一、效果展示

1.用户交流


二、准备工作

一、前端框架,Vue + elementUI组件 +JsCookie

新建一个vue项目

引入以下组件与依赖

npm i element-ui -S
npm install js-cookie

二、后端 SpringBoot + websocket包

创建SpringBoot项目后

在pom.xml文件中引入以下依赖:

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>

注意项目前端为8081端口,后端为8080端口,所以先运行后端再运行前端


三、前端代码

在App.vue中即可引入以下代码:

html:

<template><div id="Layout"><el-container><el-aside width="200px">Aside</el-aside><el-container><el-header style="background-color: rgb(245, 245, 245); border-bottom: 1px solid grey;"><h3>聊天广场</h3></el-header><el-main style="background-color: rgb(244, 245, 247);min-height: 700px; max-height: 700px; "><div id="chatContent" style="padding-left: 10px; line-height: normal; "><!-- 循环输出对话内容 --><el-scrollbar v-for="(message, index) in messages" :key="index"><div ref="scrollbar" v-if="message.sender !== senderName" class="chat-message" id="ChatContentCard" style=" background-color: white;margin-top: 20px; box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)  "><el-avatar :size="40"src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"></el-avatar><div class="message-content" style="width: 100%;"><div style="text-align: left; text-indent: 1em;"> {{ message.sender }}</div><div id="chatContentText">{{ message.text }}</div></div></div><div ref="scrollbar" v-if="message.sender === senderName" id="myChatContentCard"><el-avatar :size="40"src="https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg"></el-avatar><div class="message-content" style="width: 100%;"><div style="text-align: left; text-indent: 1em;"> {{ message.sender }}</div><div id="chatContentText">{{ message.text }}</div></div></div></el-scrollbar></div></el-main><!-- 底层交互框 --><el-footer style="height: 190px; background-color: rgb(244, 245, 247); "><div id="Gadget" style="background-color: rgb(244, 245, 247); height: 35px; margin-bottom: 10px;"><el-upload class="upload-demo" ref="upload" action="https://jsonplaceholder.typicode.com/posts/":on-preview="handlePreview" :on-remove="handleRemove" :file-list="fileList" :auto-upload="false" style="float: left;"><el-button slot="trigger" size="small" type="primary"><i class="el-icon-picture-outline-round"></i></el-button><el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button></el-upload></div><el-form @submit.native.prevent="sendMessage"style="background-color: rgb(244, 245, 247); height: 80%; width: 100%; position: relative;"><el-input v-model="messageInput" rows="4" resize="none" type="textarea" placeholder="请输入内容......."@keyup.enter="sendMessage" style="height: 100%; max-height: 60px; "></el-input><div style="text-align: right; background-color: rgb(244, 245, 247); margin-top: 34px;"><el-button type="primary" @click="sendMessage">发送</el-button></div></el-form></el-footer></el-container></el-container></div>
</template>

script:

<script>
import Cookies from 'js-cookie';export default {computed: {senderName() {return Cookies.get('account') || '游客';}},name: 'App',data() {return {messages: [],messageInput: '',ws: null,fileList: []};},mounted() {this.initWebSocket();},beforeDestroy() {this.closeWebSocket();},methods: {initWebSocket() {this.ws = new WebSocket('ws://localhost:8080/chat');this.ws.onopen = () => {console.log('Connected to server.');};this.ws.onmessage = (event) => {try {let messageData;if (isJson(event.data)) {messageData = JSON.parse(event.data);} else {messageData = { text: event.data };}this.messages.push({sender: messageData.sender || 'Anonymous',text: messageData.text,});// 使用Vue.nextTick确保DOM更新后再执行滚动操作this.$nextTick(() => {// 确保scrollbar存在且已渲染if (this.$refs.scrollbar) {// 直接滚动到底部,不需要使用contentSize// this.$refs.scrollbar.$el.scrollTop = this.$refs.scrollbar.$el.scrollHeight;}});} catch (error) {console.error('Error parsing message:', error);}};// 辅助函数,检查字符串是否可能是JSON格式function isJson(str) {try {JSON.parse(str);} catch (e) {return false;}return true;}this.ws.onerror = (error) => {console.error('WebSocket error:', error);};this.ws.onclose = () => {console.log('Disconnected from server.');};},sendMessage() {console.log('调用sendMessage');const senderName = Cookies.get('account');if (senderName === null) {this.senderName = "游客";}if (this.messageInput.trim() !== '') {this.ws.send(JSON.stringify({ sender: senderName, text: this.messageInput }));this.messageInput = ''; // 清空输入框}},closeWebSocket() {if (this.ws && this.ws.readyState === WebSocket.OPEN) {this.ws.close();}},// 文件上传函数
submitUpload() {this.$refs.upload.submit();},handleRemove(file, fileList) {console.log(file, fileList);},handlePreview(file) {console.log(file);}},
};
</script>

css:

<style scoped>
.chat-message {display: flex;align-items: center;margin-bottom: 10px;
}.message-content {margin-left: 10px;
}#Layout {line-height: normal;
}/* 添加动画关键帧 */
@keyframes slideInFromLeft {0% {transform: translateX(-100%);opacity: 0;}100% {transform: translateX(0);opacity: 1;}
}#ChatContentCard {min-height: 80px;width: 50%;/* 应用动画 */animation: slideInFromLeft 0.3s ease-in-out forwards;border-radius: 30px
}#chatContentText {width: 99%;overflow-wrap: break-word;}.el-header,
.el-footer {background-color: #B3C0D1;color: #333;text-align: center;line-height: 60px;
}.el-aside {background-color: #D3DCE6;color: #333;text-align: center;line-height: 200px;
}.el-main {background-color: #E9EEF3;color: #333;text-align: center;line-height: 160px;
}body>.el-container {margin-bottom: 40px;
}.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {line-height: 260px;
}.el-container:nth-child(7) .el-aside {line-height: 320px;
}#myChatContentCard{display: flex;align-items: center;margin-bottom: 10px;margin-left: 50%;min-height: 80px;width: 50%;/* 应用动画 */animation: slideInFromRight 0.3s ease-in-out forwards;border-radius: 30px;background-color: rgb(149, 236, 105);margin-top: 20px; box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04) }@keyframes slideInFromRight {0% {transform: translateX(100%);opacity: 0;}100% {transform: translateX(0);opacity: 1;}
}</style>

注意: 这个项目中如果script需要进行修改,由于我这里完成了一个登陆系统,所以采用了对Cookie的使用,而如果只是体验的话,只需要把Cookie去掉将其改为游客+随机字符串去替代即可。

前端启动

npm run serve


四、后端代码

WebSocket配置:

1.WebSocketConfig.java

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(new ChatWebSocketHandler(), "/chat").setAllowedOrigins("*");}
}

 2.ChatWebSocketHandler.java

@Slf4j
public class ChatWebSocketHandler extends TextWebSocketHandler {private static final Set<WebSocketSession> sessions = Collections.synchronizedSet(new HashSet<>());@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {sessions.add(session);broadcast("欢迎新的小伙伴加入");}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {broadcast(message.getPayload());}private void broadcast(String message) {log.info("服务器广播数据:"+message);sessions.forEach(session -> {try {session.sendMessage(new TextMessage(message));} catch (Exception e) {e.printStackTrace();}});}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {sessions.remove(session);}
}

 后端启动:

 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/370569.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

手写实现一个ORM框架

手写实现一个ORM框架 什么是ORM框架、ORM框架的作用效果演示框架设计代码细节SqlBuilderSqlExecutorStatementHandlerParameterHandlerResultSetHandler逆序生成实体类 大家好&#xff0c;本人最近写了一个ORM框架&#xff0c;想在这里分享给大家&#xff0c;让大家来学习学习。…

C++ 多态篇

文章目录 1. 多态的概念和实现1.1 概念1.2 实现1.2.1 协变1.2.2 析构函数1.2.3 子类虚函数不加virtual 2. C11 final和override3.1 final3.2 override 3. 函数重载、重写与隐藏4. 多态的原理5. 抽象类6.单继承和多继承的虚表6.1 单继承6.2 多继承 7. 菱形继承的虚表(了解)7.1 菱…

I/O多路复用

参考面试官&#xff1a;简单说一下阻塞IO、非阻塞IO、IO复用的区别 &#xff1f;_unix环境编程 阻塞io和非阻塞io-CSDN博客 同步阻塞(BIO) BIO 以流的方式处理数据 应用程序发起一个系统调用&#xff08;recvform&#xff09;&#xff0c;这个时候应用程序会一直阻塞下去&am…

Interview preparation--Https 工作流程

HTTP 传输的弊端 如上图&#xff0c;Http进行数据传输的时候是明文传输&#xff0c;导致任何人都有可能截获信息&#xff0c;篡改信息如果此时黑客冒充服务器&#xff0c;或者黑客窃取信息&#xff0c;则其可以返回任意信息给客户端&#xff0c;而且不被客户端察觉&#xff0c;…

2、图形验证码

1、图形验证码设计 1.1思路 现今&#xff0c;市面上的图形验证码付费的&#xff0c;免费的多种多样&#xff0c;主要形式有滑动拼图、文字点选、语序点选、字体识别、空间推理、智能随机等。 而处理也分为web端和sever端两部分 此处以免费的kaptcha 为例&#xff0c;进行数字图…

认识流式处理框架Apache Flink

目录 一、Apache Flink 的基础概念 1.1 Apache Flink是什么&#xff1f; 1.2 Flink的定义 二、Apache Flink 的发展史 2.1 Flink前身Stratosphere 2.2 Flink发展时间线及重大变更 三、Flink核心特性 3.1 批流一体化 3.2 同时支持高吞吐、低延迟、高性能 3.3 支持事件时…

全新UI自助图文打印系统小程序源码 PHP后端 附教程

最新自助图文打印系统和证件照云打印小程序源码PHP后端&#xff0c;为用户用户自助打印的服务&#xff0c;包括但不限于文档、图片、表格等多种格式的文件。此外&#xff0c;它们还提供了诸如美颜、换装、文档打印等功能&#xff0c;以及后台管理系统&#xff0c;方便管理员对打…

小(微)间距P1.538COB渠道现货销售将加速全面升级替换SMD产品。

COB&#xff08;Chip on Board&#xff09;技术&#xff0c;如一颗璀璨的星辰&#xff0c;在上世纪60年代的科技夜空中悄然升起。它巧妙地将LED芯片镶嵌在PCB电路板的怀抱中&#xff0c;再用特种树脂为其披上一层坚韧的外衣&#xff0c;宛如一位精心雕琢的艺术家在创作一幅完美…

实战whisper第三天:fast whisper 语音识别服务器部署,可远程访问,可商业化部署(全部代码和详细部署步骤)

Fast Whisper 是对 OpenAI 的 Whisper 模型的一个优化版本,它旨在提高音频转录和语音识别任务的速度和效率。Whisper 是一种强大的多语言和多任务语音模型,可以用于语音识别、语音翻译和语音分类等任务。 Fast Whisper 的原理 Fast Whisper 是在原始 Whisper 模型的基础上进…

从0到1:培训老师预约小程序开发笔记二

背景调研 培训老师预约小程序&#xff1a; 教师和学生可以更便捷地安排课程&#xff0c;并提升教学质量和学习效果&#xff0c;使之成为管理和提升教学效果的强大工具。培训老师可以在小程序上设置自己的可预约时间&#xff0c;学员可以根据老师的日程安排选择合适的时间进行预…

Studying-代码随想录训练营day27| 贪心算法理论基础、455.分发饼干、376.摆动序列、53.最大子序和

第27天&#xff0c;贪心开始&#xff01;(ง •_•)ง&#x1f4aa;&#xff0c;编程语言&#xff1a;C 目录 贪心算法理论基础 贪心的套路 贪心的一般解题步骤 总结 455.分发饼干 376.摆动序列 53.最大子序和 总结 贪心算法理论基础 什么是贪心&#xff1f;—— 贪…

计算机组成原理学习笔记(一)

计算机组成原理 [类型:: [[计算机基础课程]] ] [来源:: [[B站]] ] [主讲人:: [[咸鱼学长]] ] [评价:: ] [知识点:: [[系统软件]] & [[应用软件]] ] [简单解释:: 管理计算机系统的软件&#xff1b; 按照任务需要编写的程序 ] [问题:: ] [知识点:: [[机器字长]] ] [简单…

三相感应电机的建模仿真(2)基于ABC相坐标系S-Fun的仿真模型

1. 概述 2. 三相感应电动机状态方程式 3. 基于S-Function的仿真模型建立 4. 瞬态分析实例 5. 总结 6. 参考文献 1. 概述 前面建立的三相感应电机在ABC相坐标系下的数学模型是一组周期性变系数微分方程&#xff08;其电感矩阵是转子位置角的函数&#xff0c;转子位置角随时…

ubuntu22 sshd设置

专栏总目录 一、安装sshd服务 sudo apt updatesudo apt install -y openssh-server 二、配置sshd 使用文本编辑器打开/etc/ssh/sshd_config sudo vi /etc/ssh/sshd_config &#xff08;一&#xff09;配置sshd服务的侦听端口 建议将ssh的侦听端口改为7000以上的端口&#…

安装 tesseract

安装 tesseract 1. Ubuntu-24.04 安装 tesseract2. Ubuntu-24.04 安装支持语言3. Windows 安装 tesseract4. Oracle Linux 8 安装 tesseract 1. Ubuntu-24.04 安装 tesseract sudo apt install tesseract-ocr sudo apt install libtesseract-devreference: https://tesseract-…

Android- Framework 非Root权限实现修改hosts

一、背景 修改system/etc/hosts&#xff0c;需要具备root权限&#xff0c;而且remount后&#xff0c;才能修改&#xff0c;本文介绍非root状态下修改system/etc/hosts方案。 环境&#xff1a;高通 Android 13 二、方案 非root&#xff0c;system/etc/hosts只有只读权限&…

【分布式系统】ELK 企业级日志分析系统

目录 一.ELK概述 1.简介 1.1.可以添加的其他组件 1.2.filebeat 结合 logstash 带来好处 2.为什么使用ELK 3.完整日志系统基本特征 4.工作原理 二.部署ELK日志分析系统 1.初始化环境 2.完成JAVA部署 三. ELK Elasticsearch 集群部署 1.安装 2.修改配置文件 3.es 性…

Linux运维之管道符、重定向与环境变量

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 目录 一、输入输出重定向 二、管道命令符 三、命令行的通配符 四、常用的转义字符 五、重要的环境变量 致谢 一、输入输出重定向 输入重定向是…

《昇思25天学习打卡营第13天|onereal》

今天学习的内容如下&#xff1a; DCGN生成漫画头像 在下面的教程中&#xff0c;我们将通过示例代码说明DCGAN网络如何设置网络、优化器、如何计算损失函数以及如何初始化模型权重。在本教程中&#xff0c;使用的动漫头像数据集共有70,171张动漫头像图片&#xff0c;图片大小均为…

进程控制-exec函数

让父子进程来执行不相干的操作 能够替换进程地址空间的代码.text段 执行另外的程序&#xff0c;不需要创建额外的的地址空间 当前程序中调用另外一个应用程序 指定执行目录下的程序 int execl(const char *path, const char *arg&#xff0c;/* (char *) NULL */); /* pat…