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

WebSocket —— 在线聊天室

文章目录

  • 消息推送常用方式介绍
    • 轮询
    • SSE(server-sent event)
  • websocket介绍
  • websocket API
    • 前端API
    • 后端API
  • 实现在线聊天室
    • 需求与最终效果展示
    • 实现流程分析
    • 消息格式
    • 代码实现
    • HttpSession的保存传递
    • 具体代码
      • 依赖
      • pojo
        • Result
        • User
        • Message
        • ResultMessage
      • Config
        • WebsocketConfig
        • GetHttpSessionConfig
      • Controller
        • UserController
      • Websocket
        • ChatEndpoint
      • utils
        • MessageUtils
    • 测试
      • 注意事项
      • 用户登录与连接Websocket
        • 测试
        • 过程分析
        • 响应
      • 用户私聊
        • 测试
        • 过程分析
        • 响应
      • 用户下线,断开Websocket
        • 测试
        • 过程分析
        • 响应

消息推送常用方式介绍

轮询

在这里插入图片描述

SSE(server-sent event)

在这里插入图片描述

websocket介绍

在这里插入图片描述

在这里插入图片描述

websocket API

前端API

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

后端API

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

实现在线聊天室

需求与最终效果展示

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

实现流程分析

在这里插入图片描述

消息格式

在这里插入图片描述

代码实现

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

HttpSession的保存传递

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

这二者这里可以视为一个东西!!!HttpSession通过这个来保存传递!

具体代码

依赖

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

pojo

Result
@Data
public class Result {private boolean flag;private String message;
}
User
@Data
public class User {private String userId;private String username;private String password;}
Message
@Data
public class Message {private String toName;private String message;
}
ResultMessage
@Data
public class ResultMessage {private boolean isSystem;private String fromName;private Object message;
}

Config

WebsocketConfig
@Configuration
public class WebsocketConfig {/*** ServerEndpointExporter 的作用** 自动注册 WebSocket 端点* ServerEndpointExporter 会自动扫描 Spring 容器中所有带有 @ServerEndpoint 注解的类,并将它们注册为 WebSocket 端点。* 这意味着你不需要手动在 Spring 容器中注册这些端点,ServerEndpointExporter 会自动处理。** 支持 Spring 的依赖注入* 通过 ServerEndpointExporter,Spring 容器中的 WebSocket 端点可以像其他 Spring Bean 一样使用依赖注入(DI)。* 例如,你可以在 WebSocket 端点类中注入其他 Spring Bean,如服务层(Service)或工具类(Utility)。** 简化 WebSocket 配置* 使用 ServerEndpointExporter 可以简化 WebSocket 的配置,避免手动编写大量的配置代码。* 它提供了一种声明式的方式来配置 WebSocket 端点,使得代码更加简洁和易于维护。* @return*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}
GetHttpSessionConfig
public class GetHttpSessionConfig extends ServerEndpointConfig.Configurator {@Overridepublic void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {//获取HttpSession对象HttpSession httpSession = (HttpSession)request.getHttpSession();//将httpSession对象保存起来sec.getUserProperties().put(HttpSession.class.getName(),httpSession);}}

Controller

UserController
/*** @CrossOrigin 是 Spring Framework 提供的一个注解,用于解决跨域资源共享(Cross-Origin Resource Sharing, CORS)问题。* 可以应用于 Spring MVC 控制器类或方法上,用于配置允许跨域请求的规则。* 它支持多种配置选项,包括允许的域、HTTP 方法、请求头等。*/
@CrossOrigin
@RestController
@RequestMapping("/user")
public class UserController {/**** @param user* @param session 在 Spring MVC 中,HttpSession 是通过 Spring 的 @Controller 方法参数自动注入的。当你在方法签名中声明一个 HttpSession 参数时,*                Spring 会自动从当前的 HTTP 请求中获取对应的 HttpSession 对象,并将其传递给方法。** HttpSession 的生命周期* 创建:当第一个请求到达服务器时,如果请求中没有 JSESSIONID(表示没有已存在的会话),Spring MVC 会创建一个新的 HttpSession。* 存储:HttpSession 对象存储在服务器端,与客户端通过 JSESSIONID 进行关联。* 访问:在后续的请求中,客户端会通过 JSESSIONID 来标识当前会话,服务器会根据 JSESSIONID 找到对应的 HttpSession。* 销毁:当用户关闭浏览器或会话超时后,HttpSession 会被销毁。* @return*/@PostMapping("/login")public Result login(@RequestBody User user, HttpSession session) {Result result = new Result();if (user != null && "123".equals(user.getPassword())) {result.setFlag(true);//将数据存储到session对象中session.setAttribute("user", user.getUsername());} else {result.setFlag(false);result.setMessage("登录失败");}return result;}}

Websocket

ChatEndpoint
@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfig.class)
@Component
public class ChatEndpoint {private static final Map<String, Session> onlineUsers = new ConcurrentHashMap<>();private HttpSession httpSession;/*** 建立websocket连接后,被调用* @param session*/@OnOpenpublic void onOpen(Session session, EndpointConfig config) {//将session进行保存this.httpSession = (HttpSession)config.getUserProperties().get(HttpSession.class.getName());String username = (String) this.httpSession.getAttribute("user");onlineUsers.put(username, session);//广播消息,需要将登录的所有用户推送给所有的用户String message = MessageUtils.getMessage(true, null, getFriends());broadcastAllUsers(message);}public Set getFriends() {return onlineUsers.keySet();}private void broadcastAllUsers(String message) {try {//遍历map集合Set<Map.Entry<String, Session>> entries = onlineUsers.entrySet();for (Map.Entry<String, Session> entry : entries) {//获取到所有用户对应的session对象Session session = entry.getValue();//发送消息session.getBasicRemote().sendText(message);}} catch (Exception e) {throw new RuntimeException(e);}}/*** 浏览器发送消息到服务端,该方法被调用* @param message*/@OnMessagepublic void onMessage (String message) {try {//将消息推送给指定的用户Message msg = JSONObject.parseObject(message, Message.class);//获取 消息接收方的用户名String toName = msg.getToName();String mess = msg.getMessage();//获取 消息接收方的 session对象Session session = onlineUsers.get(toName);String username = (String) this.httpSession.getAttribute("user");session.getBasicRemote().sendText(MessageUtils.getMessage(false, (String)httpSession.getAttribute("user"), mess));} catch (Exception e) {throw new RuntimeException(e);}}/*** 断开websocket连接时被调用* @param session*/@OnClosepublic void onClose(Session session) {//从onlineUsers中剔除当前用户的session对象String username = (String) this.httpSession.getAttribute("user");onlineUsers.remove(username);//通知其他用户,当前用户下线了broadcastAllUsers(MessageUtils.getMessage(true, null, getFriends()));}
}

utils

MessageUtils
public class MessageUtils {public static String getMessage(boolean isSystemMessage, String fromName, Object message) {ResultMessage result = new ResultMessage();result.setSystem(isSystemMessage);result.setMessage(message);if (fromName != null) {result.setFromName(fromName);}return JSON.toJSONString(result);}
}

测试

注意事项

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

用户登录与连接Websocket

测试

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

过程分析

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

广播时沟通传递JSON格式数据,因此message记得从实体类转为JSON
获取HttpSession对象后要保存起来成为成员变量,方便后续使用
以及要将其中username信息和对应的Session映射保存起来,方便后续使用!!!

在这里插入图片描述

响应

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

用户私聊

测试

在这里插入图片描述

过程分析

在这里插入图片描述

响应

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

用户下线,断开Websocket

测试

在这里插入图片描述

过程分析

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

在这里插入图片描述

响应

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

在这里插入图片描述

http://www.dtcms.com/a/473564.html

相关文章:

  • 我的高清手机大屏
  • MySQL(三) - 表中数据增删改操作
  • [嵌入式系统-101]:AIoT(人工智能物联网)开发板
  • 成都装修网站制作免费一键网站
  • 2025版spring security认证授权详解篇【经典】
  • 第五十五章 ESP32S3 基于MQTT协议连接OneNet物联网开放平台
  • MySQL可重复读的级别下,幻读本质问题
  • MaixCam二维云台检测人脸项目
  • 无线收发系统结构
  • 做网站的工作是什么开发公司官网
  • Node.js 与 MongoDB:高效的数据管理解决方案
  • 网络层:从 IP 协议到路由转发
  • 做网站办什么营业执照nginx wordpress 伪静态
  • 深入理解TCP/IP通信:系统调用与零拷贝技术全面解析
  • 编程语言Delphi
  • 【AI论文】RLP:将强化学习作为预训练目标
  • Etcd使用
  • etcd实战课-实战篇(上)
  • Kubernetes 运维指南:kubectl 命令全解析
  • 网站logo关键字参数
  • ubuntu下桌面应用启动图标的内容文件
  • Leetcode 25
  • 西安博达网站建设自己制作wordpress plugin
  • OpenCV的数据类型二
  • Serdes专题(3)Lattice Serdes架构
  • 人形机器人项目中使用Ubuntu-Server安装桌面系统进行远程xrdp远程连接操作
  • 京东开源了一款大模型安全框架:JoySafety,说是京东内部已应用,实现95%+攻击拦截率
  • 【传奇开心果系列】基于Flet框架实现的关于页面创建和提供文件下载集成了网络请求、文件下载、剪贴板操作功能自定义模板特色和实现原理深度解析
  • ​为什么我们需要将Flow转换为StateFlow?​​
  • vscode远程连接云服务器的初次尝试