java--WebSocket简单介绍
一、什么是 WebSocket?
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,常用于客户端与服务端之间频繁通信的场景。它允许客户端和服务器互相推送数据,突破了 HTTP 的“请求-响应”模式。
📌 特点:
建立连接后,客户端和服务端都可以主动发送数据
使用标准的
ws://
或加密的wss://
协议性能高、低延迟、低带宽开销
🧠 它与传统 HTTP 的区别:
项目 HTTP WebSocket 通信方式 请求-响应,客户端主动 全双工通信,双方主动 长连接 ❌ 短连接 ✅ 长连接(建立后保持) 传输效率 低(每次请求都带完整头信息) 高(建立后轻量数据帧) 建立方式 无需特殊处理 通过一次 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