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

java--WebSocket简单介绍

一、什么是 WebSocket?

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,常用于客户端与服务端之间频繁通信的场景。它允许客户端和服务器互相推送数据,突破了 HTTP 的“请求-响应”模式。

📌 特点:

  • 建立连接后,客户端和服务端都可以主动发送数据

  • 使用标准的 ws:// 或加密的 wss:// 协议

  • 性能高、低延迟、低带宽开销

🧠 它与传统 HTTP 的区别:

项目HTTPWebSocket
通信方式请求-响应,客户端主动全双工通信,双方主动
长连接❌ 短连接✅ 长连接(建立后保持)
传输效率低(每次请求都带完整头信息)高(建立后轻量数据帧)
建立方式无需特殊处理通过一次 HTTP 握手升级协议


二、WebSocket 的应用场景

WebSocket 非常适合这些场景:

  • 实时聊天(如客服系统、社交 IM)

  • 实时通知(如订单状态、系统告警)

  • 在线协同编辑

  • 实时行情(如股票、比特币)

  • Web 游戏

  • 实时日志/监控推送

  • 实时进度条(如后台任务进度)


三、Java 中如何使用 WebSocket?

Java 提供两种主流方式:

✅ 方式一:Java 标准 API(JSR-356)

  • 使用 @ServerEndpoint 注解

  • 需配合 ServerEndpointExporter 使用(SpringBoot 环境中)

@ServerEndpoint("/ws")
public class MyWebSocket {@OnOpenpublic void onOpen(Session session) {System.out.println("连接建立:" + session.getId());}@OnMessagepublic void onMessage(String message, Session session) {System.out.println("收到消息:" + message);}@OnClosepublic void onClose(Session session) {System.out.println("连接关闭:" + session.getId());}
}

✅ 方式二:Spring Boot 封装方式(推荐)

  • 实现 WebSocketHandler

  • 更灵活,支持依赖注入、拦截器等

  • 适合结合 Spring Boot 项目使用


四、Spring Boot 整合 WebSocket 的完整例子

下面是一个使用 Spring Boot 实现 WebSocket 的完整示例:

✅ 1)核心依赖(pom.xml

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

✅ 2)WebSocket 处理器

@Component
@Slf4j
public class MyWsHandler extends AbstractWebSocketHandler {// 存储所有连接的客户端 session,key 是 sessionIdprivate static final Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>();// 建立连接时调用@Overridepublic void afterConnectionEstablished(WebSocketSession session) {sessionMap.put(session.getId(), session); // 保存连接log.info("连接建立:" + session.getId());}// 收到客户端消息时调用@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {log.info("收到消息:" + message.getPayload());// 回复客户端session.sendMessage(new TextMessage("你发送的是:" + message.getPayload()));}// 连接关闭时调用@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) {sessionMap.remove(session.getId()); // 移除连接log.info("连接关闭:" + session.getId());}
}

✅ 3)握手拦截器(可选)

@Component
@Slf4j
public class MyWsInterceptor extends HttpSessionHandshakeInterceptor {// 握手前(可用于校验 token、记录 IP 等)@Overridepublic boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,WebSocketHandler wsHandler, Map<String, Object> attributes) {log.info("握手开始:" + request.getRemoteAddress());return true; // 返回 true 表示允许连接}// 握手完成后@Overridepublic void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,WebSocketHandler wsHandler, Exception ex) {log.info("握手完成:" + request.getRemoteAddress());}
}

✅ 4)配置类:注册路径和拦截器

@Configuration
@EnableWebSocket // 启用 WebSocket 支持
public class MyWsConfig implements WebSocketConfigurer {@Autowiredprivate MyWsHandler myWsHandler;@Autowiredprivate MyWsInterceptor myWsInterceptor;// 注册 handler 以及路径、拦截器、跨域设置@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myWsHandler, "/ws")       // 绑定路径 /ws.addInterceptors(myWsInterceptor)     // 绑定拦截器.setAllowedOrigins("*");              // 允许跨域连接}
}

✅ 5)前端简单测试页面(可选)

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>WebSocket 测试</title>
</head>
<body><h1>WebSocket Client</h1><button onclick="connect()">连接</button><button onclick="sendMessage()">发送消息</button><script>let socket;function connect() {socket = new WebSocket("ws://localhost:8080/ws");socket.onmessage = function(event) {alert("收到消息:" + event.data);};}function sendMessage() {socket.send("你好,服务器!");}</script>
</body>
</html>

五、常见问题

问题原因与解决
前端连接失败确认 URL 是否正确,协议是否为 ws://
@Autowired 注入失败你可能用了 @ServerEndpoint,而不是 Spring 的 Handler 方式
浏览器提示跨域设置 .setAllowedOrigins("*") 或配置 CORS
发送消息失败session 已关闭;需先判断 session.isOpen()


✅ 总结回顾

内容说明
WebSocket 是什么一种持久化、双向通信协议,替代轮询
使用场景实时消息/通知/游戏/直播/行情等
Java 使用方式@ServerEndpoint 或 Spring 的 WebSocketHandler
推荐方式Spring Boot 中优先使用 WebSocketConfigurer + WebSocketHandler

http://www.xdnf.cn/news/1199467.html

相关文章:

  • 多模态视觉语言模型FILA-细粒度分辨率融合策略
  • [10月考试] B
  • Flutter 生命周期介绍
  • 基于Java的KTV点歌系统的设计与实现
  • 电商项目_核心业务_分布式ID服务
  • [STM32][HAL]stm32wbxx 超声波测距模块实现(HY-SRF05)
  • selenium完整版一览
  • 三、搭建springCloudAlibaba2021.1版本分布式微服务-springcloud loadbalancer负载均衡
  • git 提交时排除一个或多个文件
  • 【H264视频编码】一、基本概念
  • 沪深L2逐笔十档委托队列分时Tick历史数据分析处理
  • 集合框架学习
  • day25
  • vulkan从小白到专家——YUV处理
  • Windows|CUDA和cuDNN下载和安装,默认安装在C盘和不安装在C盘的两种方法
  • 《谁在翻译机器的疼痛?》——故障诊断的认知鸿沟与产教破壁之战!
  • C++ 多线程(一)
  • 低精度训练一:低精度训练介绍与大模型下载
  • 09_opencv_遍历操作图像像素
  • net8.0一键创建支持(RabbitMQ)
  • 【AI论文】WebShaper:通过信息寻求形式化实现主动式数据合成
  • 深入理解Java内存与运行时机制:从对象内存布局到指针压缩
  • 【C++】红黑树实现
  • n8n “Run Once for All Items“和“Run Once for Each Item“区别
  • 基于Springboot+UniApp+Ai实现模拟面试小工具七:前端项目创建及框架搭建
  • cJSON在STM32单片机上使用遇到解析数据失败问题
  • Java面试全栈通关:从微服务到AI的技术深度解析
  • 一文读懂 JWT(JSON Web Token)
  • 【LeetCode刷题指南】--设计循环队列
  • 怎样让阿里云服务器(centos)有界面