WebSocket 实时聊天

ops/2025/1/19 5:07:36/

源码

源码包括:

  • 源码地址 : websocket-gitee仓库
  • websocket 聊天室,前后端代码
  • websocket 查看历史消息
  • 采用springsecurity作为鉴权
  • 前端代码在 resources static 下,好处:打开springboot端口就是改页面:
    – 例如:localhost:8080
  • 项目采用渐进式,共有四个项目

在这里插入图片描述

坐标导入

由于SpringBoot集成WebSocket,因此版本号即为springboot版本号,一般情况无需配置版本号

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

配置文件

在springboot集成的websocket中,主要操作的是Session

Session配置

public class SessionConfig extends ServerEndpointConfig.Configurator {@Overridepublic void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {HttpSession httpSession = (HttpSession) request.getHttpSession();if (httpSession != null) {sec.getUserProperties().put(HttpSession.class.getName(), httpSession);System.out.println("[websocket] 获取HttpSession成功");} else {System.err.println("在WebSocket握手期间HttpSession为空");}}
}

服务类

配置请求 ws:// 地址,使用配置类
处理连接中常用的四种状态 :

  • 连接打开
  • 消息处理
  • 连接异常
  • 连接关闭
@Slf4j
@ServerEndpoint(value = "/ws", configurator = SessionConfig.class)
public class ChatChannel{private Session session;// 连接打开@OnOpenpublic void onOpen(Session session, EndpointConfig endpointConfig){// 保存 session 到对象this.session = session;//获取存储的用户信息Object o = endpointConfig.getUserProperties().get(HttpSession.class.getName());log.info("[websocket] 新的连接:用户id{} id={}", o, this.session.getId());}// 收到消息@OnMessagepublic void onMessage(String message) throws IOException{log.info("[websocket] 收到消息:id={},message={}", this.session.getId(), message);this.session.getAsyncRemote().sendText("[" + Instant.now().toEpochMilli() + "] Hello " + message);}// 连接关闭@OnClosepublic void onClose(CloseReason closeReason){log.info("[websocket] 连接断开:id={},reason={}", this.session.getId(), closeReason);}// 连接异常@OnErrorpublic void onError(Throwable throwable) throws IOException{log.info("[websocket] 连接异常:id={},throwable={}", this.session.getId(), throwable.getMessage());// 关闭连接。状态码为 UNEXPECTED_CONDITION(意料之外的异常)this.session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, throwable.getMessage()));}
}

websocket_90">配置websocket服务

主要目的 : 告诉spring将服务自动装配到bean容器中

@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {ServerEndpointExporter exporter = new ServerEndpointExporter();exporter.setAnnotatedEndpointClasses(ChatChannel.class);return exporter;}
}

连接测试

为了简化,这里采用连接工具 : ApiPost

在这里插入图片描述
在这里插入图片描述

关于连接异常

关于连接异常的文章查看我的内外一篇文章:
websocket 连接异常


http://www.ppmy.cn/ops/151278.html

相关文章

【概率论与数理统计】第三章 多维随机变量及其分布(1)

1 多维随机变量的概念 1.1 二维随机变量及其分布函数 在实际问题中&#xff0c;通常需要多个随机变量才能较好地描述某一随机现象&#xff1b;例如&#xff0c;打靶时&#xff0c;弹着点是由两个随机变量所构成的&#xff08;横、纵坐标&#xff09;&#xff1b;飞机重心在空…

linux下的线程

一、pthread 线程 线程可以说是轻量级的进程&#xff0c;一般是一个进程中的多个任务。 进程&#xff1a;系统中的最小资源分配单元 线程:系统中最小执行单元 二、线程的特征 1、共享资源 2、效率高30% 3.使用第三方库&#xff08;头文件加pthread.h 编译时添加 -lpthre…

视频本地化的特点

视频本地化是一个多方面的过程&#xff0c;涉及为特定的语言和文化市场调整视听内容。当由本地专业人员处理时&#xff0c;这个过程达到了自动化工具或非本地专家难以达到的深度和真实性水平。母语人士对语言、文化背景和观众期望有着细致入微的理解&#xff0c;这对于创建与不…

开始使用Panuon开源界面库环境配置并手写VS2019高仿界面

1. Panuon环境配置 1.1. 通过Nuget 安装 Panuon.WPF.UI1.2. xaml引用命名空间1.3. using Panuon.WPF.UI; 2. VS2019 view 2.1. 设置窗体尺寸和title2.2. 添加静态资源 2.2.1. 什么是静态资源 2.3. 主Grid 2.3.1. 盒子模型2.3.2. 嵌套布局 3. 总结 1. Panuon环境配置 1.1. 通…

Web前端------HTML多媒体标签之音频和视频标签

一.音频和视频标签介绍 <audio></audio> 网页中支持播放音频的标签&#xff0c;经常用于给网页添加背景音乐&#xff1b;音频播放网站常用 audio标签&#xff0c;支持网页中播放音频数据注意&#xff1a;需要将支持的mp3文件&#xff0c;保存在指定文件夹中 audi…

idea本地jar包添加到项目的maven库 mvn install:install-file

背景 最近在开发项目中需要对接海康威视摄像头&#xff0c;进行视频、照片等数据的获取保存&#xff1b;海康提供的sdk的jar包是自己开发的&#xff0c;在maven库中是找不到的&#xff0c;在项目中需要手动指定jar包路径 <dependency><groupId>com.haikang</g…

【SpringBoot】深度解析 Spring Boot 拦截器:实现统一功能处理的关键路径

前言 ???本期讲解关于拦截器的详细介绍~~~ ??感兴趣的小伙伴看一看小编主页&#xff1a;-CSDN博客 ?? 你的点赞就是小编不断更新的最大动力 ??那么废话不多说直接开整吧~~ 目录 ???1.拦截器 ??1.1拦截器快速入门 1.?定义拦截器 2.配置拦截器 ??1.2拦…

sql server 常用运维SQL

12.定位SQL查询SQL语句执行时间和IO消耗 SELECT s2.dbid, (SELECT TOP 1 SUBSTRING(s2.text,statement_start_offset / 2+1 , ( (CASE WHEN statement_end_offset = -1 THEN (LEN(CONVERT(nvarchar(max),s2.text)) * 2) ELSE statement_end_offset END) - statement_start_offs…