SpringBoot整合WebSocket实现聊天室
1.简单的实现了聊天室功能,注意页面刷新后聊天记录不会保存,后端没有做消息的持久化
2.后端用户的识别只简单使用Session用户的身份
0.依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
1.配置WebSocketConfigurer配置类
package com.example.config;import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.server.HandshakeInterceptor;import javax.servlet.http.HttpSession;
import java.util.Map;@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfigurer implements WebSocketMessageBrokerConfigurer {@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {config.enableSimpleBroker("/topic");config.setApplicationDestinationPrefixes("/app");}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/ws").withSockJS().setInterceptors(new HttpHandshakeInterceptor());}public class HttpHandshakeInterceptor implements HandshakeInterceptor {@Overridepublic boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {if (request instanceof ServletServerHttpRequest) {ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;HttpSession session = servletRequest.getServletRequest().getSession(false);if (session != null) {//使用session中的userString user = (String) session.getAttribute("user");if(user!=null){attributes.put("user", user);}}}return true;}@Overridepublic void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,WebSocketHandler wsHandler, Exception exception) { }}}
2.MessageHandler用于处理接收消息
package com.example.webController;import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;import javax.servlet.http.HttpSession;@Controller
public class MessageHandler {@MessageMapping("/chat")@SendTo("/topic/messages")public String chat(@PathVariable("messages") String message, SimpMessageHeaderAccessor headerAccessor) {// 获取用户数据Object user = headerAccessor.getSessionAttributes().get("user");System.out.println("User: " + user);return user.toString()+":" + message;}//登录@GetMapping("login/{userName}")public void login(@PathVariable String userName, HttpSession session) {System.out.println("User " + userName);session.setAttribute("user", userName);}
}
3.前端页面
先登录后发送消息
4.前端代码
<!DOCTYPE html>
<html>
<head><title>WebSocket Demo</title><script src="https://cdn.jsdelivr.net/npm/sockjs-client/dist/sockjs.min.js"></script><script src="https://cdn.jsdelivr.net/npm/stompjs/lib/stomp.min.js"></script><style>#chatBox {width: 60%;margin: auto;height: 500px;border: 1px solid black;padding: 10px;border-radius: 7px;}.chat-message {height: 85%;overflow: auto;}.flex-row, .flex-row-reverse {display: flex;justify-content: space-between;padding: 10px 0;}.message {max-width: 60%;padding: 10px;border-radius: 10px;}.user {background-color: #7986cb;color: white;}.assistant {background-color: #ffe082;}#inputMessage {width: 80%;padding: 10px;border-radius: 10px;border: 1px solid black;margin-top: 10px;}#sendButton {width: 15%;margin-left: 5%;padding: 11px;background-color: #ff7043;color: white;border: none;border-radius: 10px;cursor: pointer;}</style>
</head>
<body>
<div id="chat"><div id="chatBox"><div class="chat-message"><div class="flex-row"><div class="message user"><p>Hello</p></div></div><div class="flex-row-reverse"><div class="message assistant"><p>Hi, How can I help you?</p></div></div></div><input type="text" id="inputMessage" placeholder="Type message.." /><button id="sendButton" onclick="send()">Send</button></div><input type="text" id="login" placeholder="输入用户名。。。" /><button onclick="login()">Login</button></div>
<script>var socket = new SockJS('/ws');var stompClient = Stomp.over(socket);stompClient.connect({}, function(frame) {stompClient.subscribe('/topic/messages', function(message) {var div = document.createElement('div');div.className = "flex-row-reverse";var messageDiv = document.createElement('div');messageDiv.className = "message assistant";var p = document.createElement('p');p.textContent = message.body;messageDiv.appendChild(p);div.appendChild(messageDiv);document.querySelector('.chat-message').appendChild(div);});});function login() {var value = document.getElementById('login').value;//发送get请求fetch('/login/' + value)//刷新页面window.location.reload();}function send() {var inputValue = document.getElementById('inputMessage').value;var div = document.createElement('div');div.className = "flex-row";// var messageDiv = document.createElement('div');// messageDiv.className = "message user";// var p = document.createElement('p');// p.textContent = inputValue;// messageDiv.appendChild(p);// div.appendChild(messageDiv);document.querySelector('.chat-message').appendChild(div);stompClient.send("/app/chat", {}, inputValue);document.getElementById('inputMessage').value = '';}
</script>
</body>
</html>
相关文章:
SpringBoot整合WebSocket实现聊天室
1.简单的实现了聊天室功能,注意页面刷新后聊天记录不会保存,后端没有做消息的持久化 2.后端用户的识别只简单使用Session用户的身份 0.依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-…...
llama-factory学习个人记录
框架、模型、数据集准备 1.llama-factory部署 # 克隆仓库 git clone https://github.com/hiyouga/LLaMA-Factory.git # 创建虚拟环境 conda create --name llama_factory python3.10 # 激活虚拟环境 conda activate llama_factory # 安装依赖 cd LLaMA-Factory pip install -…...
VLC播放器(全称VideoLAN Client)
一、简介 VLC播放器(全称VideoLAN Client)是一款开源的多媒体播放器,由VideoLAN项目团队开发。它支持多种音视频格式,并能够在多种操作系统上运行,如Windows、Mac OS X、Linux、Android和iOS等。VLC播放器具备播放文件…...
跟小伙伴们说一下
因为很忙,有一段时间没有更新了,这次先把菜鸟教程停更一下,因为自己要查缺补漏一些细节问题,而且为了方便大家0基础也想学C语言,这里打算给大家开一个免费专栏,这里大家就可以好好学习啦,哪怕0基…...
学 C/C++ 具体能干什么?
学习 C 和 C 后,你可以从事许多不同的工作和项目,这两种语言以其高性能和低级控制而闻名,特别适合以下几个领域: 1. 系统编程 C 和 C 是系统编程的首选语言,适用于操作系统、驱动程序和嵌入式系统开发。 操作系统开发…...
Django之Ajax实战笔记--城市级联操作
1. 项目架构搭建 1.1 创建项目tpdemo,创建应用myapp # 创建项目框架tpdemo$ django-admin startproject tpdemo$ cd tpdemo# 在项目中创建一个myapp应用$ python manage.py startapp myapp# 创建模板目录$ mkdir templates$ mkdir templates/myapp$ cd ..$ tree tpdemotpdemo…...
基于Netty实现WebSocket服务端
本文基于Netty实现WebSocket服务端,实现和客户端的交互通信,客户端基于JavaScript实现。 在【WebSocket简介-CSDN博客】中,我们知道WebSocket是基于Http协议的升级,而Netty提供了Http和WebSocket Frame的编解码器和Handler&#…...
27【Aseprite 作图】盆栽——拆解
1 橘子画法拆解 (1)浅色3 1 0;深色0 2 3 就可以构成一个橘子 (2)浅色 2 1;深色1 0 (小个橘子) (3)浅色 2 1 0;深色1 2 3 2 树根部分 (1)底部画一条横线 (2)上一行 左空2 右空1 【代表底部重心先在右】 (3)再上一行,左空1,右空1 (4)再上一行,左突出1,…...
【开源】2024最新python豆瓣电影数据爬虫+可视化分析项目
项目介绍 【开源】项目基于pythonpandasflaskmysql等技术实现豆瓣电影数据获取及可视化分析展示,觉得有用的朋友可以来个一键三连,感谢!!! 项目演示 【开源】2024最新python豆瓣电影数据爬虫可视化分析项目 项目截图…...
[JDK工具-5] jinfo jvm配置信息工具
文章目录 1. 介绍2. 打印所有的jvm标志信息 jinfo -flags pid3. 打印指定的jvm参数信息 jinfo -flag InitialHeapSize pid4. 启用或者禁用指定的jvm参数 jinfo -flags [|-]HeapDumpOnOutOfMemoryError pid5. 打印系统参数信息 jinfo -sysprops pid6. 打印以上所有配置信息 jinf…...
【Linux系统编程】进程概念、进程排队、进程标识符、进程状态
目录 什么是进程? 浅谈进程排队 简述进程属性 进程属性之进程标识符 进程操作之进程创建 初识fork fork返回值 原理角度理解fork fork的应用 进程属性之进程状态 再谈进程排队 进程状态 运行状态 阻塞状态 挂起状态 Linux下的进程状态 “R”(运行状…...
Java与GO语言对比分析
你是不是总听到go与java种种对比,其中在高并发的服务器端应用场景会有人推荐你使用go而不是 java。 那我们就从两者运行原理和基本并发设计来对比分析,看看到底怎么回事。 运行原理对比 java java 中 jdk 已经帮我们屏蔽操作系统区别。 只要我们下载并…...
Linux文件系统原理
Linux文件系统 冯诺依曼在1945年提出计算机的五大组成部分 运算器:CPU 控制器:CPU 存储器:内存和硬盘 输入设备:鼠标、硬盘 输出设备:显示器一、硬盘结构 机械硬盘结构 扇区:硬盘的最小存储单位ÿ…...
初识Spring Cache:如何简化你的缓存处理?
文章目录 1、Spring Cache介绍2、 常用注解3、 使用案例 1、Spring Cache介绍 Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。 Spring Cache 提供了一层抽象,底层可以切换不同的…...
攻防世界[GoodRe]
攻防世界[GoodRe] 学到知识: 逆向的精髓:三分懂,七分蒙。TEA 算法快速识别(蒙): 数据处理的形式:进入加密时的数据和加密结束后的数据,处理时数据的分组等等,都能用来…...
IntelliJ IDEA实用插件:轻松生成时序图和类图
IntelliJ IDEA生成时序图、类图 一、SequenceDiagram1.1 插件安装1.2 插件设置1.3 生成时序图 二、PlantUML Integration2.1 插件安装2.2 插件设置2.3 生成类图 在软件建模课程的学习中,大家学习过多种图形表示方法,这些图形主要用于软件产品设计。在传统…...
SpringBoot + Mybatis-Plus中乐观锁实现
悲观锁 悲观锁是一种悲观思想,它认为数据很可能会被别人所修改 所以总会对数据进行上锁,读操作和写操作都会上锁,性能较低,使用较少! 乐观锁 乐观锁是一种乐观思想,它认为数据并不一定会被别人所修改 所以…...
设计模式深度解析:分布式与中心化,IT界两大巨头“华山论剑”
🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》《MYSQL应用》 💪🏻 制定明确可量化的目标,坚持默默的做事。 ✨IT界的两大巨头交锋✨ 👋 在IT界的广阔天地中,有两座…...
转行一年了
关注、星标公众号,直达精彩内容 ID:技术让梦想更伟大 整理:李肖遥 来公司一年了。 说是转行其实还是在半导体行业,熟悉我的朋友知道 ,我在18年开始进入半导体行业,那个时候想着行业很重要,站对了…...
【LeetCode 151】反转字符串中的单词
1. 题目 2. 分析 这题要是用Python写,就非常简单了。 3. 代码 class Solution:def reverseWords(self, s: str) -> str:s " ".join(reversed(s.strip().split()))return s...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
