当前位置: 首页 > article >正文

WebSocket 实时聊天

源码

源码包括:

  • 源码地址 : 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 {
    @Override
    public 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;

    // 连接打开
    @OnOpen
    public 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());
    }

    // 收到消息
    @OnMessage
    public void onMessage(String message) throws IOException{
        log.info("[websocket] 收到消息:id={},message={}", this.session.getId(), message);
        
        this.session.getAsyncRemote().sendText("[" + Instant.now().toEpochMilli() + "] Hello " + message);
    }


    // 连接关闭
    @OnClose
    public void onClose(CloseReason closeReason){
        log.info("[websocket] 连接断开:id={},reason={}", this.session.getId(), closeReason);
    }

    // 连接异常
    @OnError
    public 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服务

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

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

连接测试

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

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

关于连接异常

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


http://www.kler.cn/a/507309.html

相关文章:

  • SpringSecurity-前后端分离
  • @Query(org.springframework.data.jpa.repository.Query)
  • C语言结构体漫谈:从平凡中见不平凡
  • 【Excel】【VBA】双列排序:坐标从Y从大到小排列之后相同Y坐标的行再对X从小到大排列
  • 人工智能之深度学习-[1]-了解深度学习
  • 灵活妙想学数学
  • 机器学习——逻辑回归
  • CFD 预测中的机器学习:在 Benchmark 应用程序上使用 Stochos
  • 使用Newtonsoft.Json插件,打包至Windows平台显示不支持
  • vite vue 动态导入图片
  • 常用的C库函数与头文件
  • laravel10.x 框架中间件实现原理
  • 使用 Tailwind CSS 的几点感触
  • 什么是基础镜像
  • 解决:ubuntu22.04中IsaacGymEnv保存视频报错的问题
  • 【Python通过UDP协议传输视频数据】(界面识别)
  • 基于微信小程序的摄影竞赛系统设计与实现(LW+源码+讲解)
  • 蓝桥杯算法|基础笔记(1)
  • 基于JavaFX+Mysql实现的报刊订阅管理系统
  • vite功能之---npm 依赖解析和预构建
  • 力扣解题汇总_JAVA
  • 仿射密码实验——Python实现(完整解析版)
  • 大模型——RAG
  • 设置完端口转发后,本机可以ping通公网设备,但公网设备无法ping通本机内网ip
  • RabbitMQ与Kafka的比较及应用
  • CSS布局与响应式