这个博客可以当做前言看,具体看这个WebSocket--简单介绍-CSDN博客

一、什么是 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 {
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("连接建立:" + session.getId());
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("收到消息:" + message);
    }

    @OnClose
    public 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 是 sessionId
    private static final Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>();

    // 建立连接时调用
    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        sessionMap.put(session.getId(), session); // 保存连接
        log.info("连接建立:" + session.getId());
    }

    // 收到客户端消息时调用
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
        log.info("收到消息:" + message.getPayload());
        // 回复客户端
        session.sendMessage(new TextMessage("你发送的是:" + message.getPayload()));
    }

    // 连接关闭时调用
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        sessionMap.remove(session.getId()); // 移除连接
        log.info("连接关闭:" + session.getId());
    }
}

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

@Component
@Slf4j
public class MyWsInterceptor extends HttpSessionHandshakeInterceptor {

    // 握手前(可用于校验 token、记录 IP 等)
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                   WebSocketHandler wsHandler, Map<String, Object> attributes) {
        log.info("握手开始:" + request.getRemoteAddress());
        return true; // 返回 true 表示允许连接
    }

    // 握手完成后
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                               WebSocketHandler wsHandler, Exception ex) {
        log.info("握手完成:" + request.getRemoteAddress());
    }
}

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

@Configuration
@EnableWebSocket // 启用 WebSocket 支持
public class MyWsConfig implements WebSocketConfigurer {

    @Autowired
    private MyWsHandler myWsHandler;

    @Autowired
    private MyWsInterceptor myWsInterceptor;

    // 注册 handler 以及路径、拦截器、跨域设置
    @Override
    public 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

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐