WebSocket 与 HTTP 的区别及 Spring Boot 实战应用

发布于:2025-06-27 ⋅ 阅读:(16) ⋅ 点赞:(0)
一、核心差异:WebSocket vs HTTP
特性 HTTP WebSocket
连接方式 短连接 (请求-响应后断开) 长连接 (持久化双向通道)
通信方向 单向 (客户端发起请求) 双向 (服务端可主动推送)
协议开销 每次请求携带完整 HTTP 头 初始握手后仅传输数据
实时性 低 (依赖轮询) 高 (毫秒级延迟)
适用场景 静态资源、API 请求 实时聊天、股票行情、协同编辑

关键区别:WebSocket 通过一次 HTTP 握手升级为全双工 TCP 连接,实现服务端主动推送能力,突破 HTTP 单向通信的限制。

二、Spring Boot 中的 WebSocket 配置

1. 添加依赖 (pom.xml)

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

2. 配置类注册 Bean

@Configuration
public class WebSocketConfiguration {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter(); // 自动注册@ServerEndpoint注解
    }
}
三、WebSocket 服务端实现
@Component
@ServerEndpoint("/ws/{sid}") // 定义WebSocket终结点路径
public class WebSocketServer {

    // 存储会话ID与Session对象的映射
    private static final Map<String, Session> sessionMap = new ConcurrentHashMap<>();

    /**
     * 连接建立成功时调用
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        sessionMap.put(sid, session);
        System.out.println("🚀 客户端连接: " + sid + " | 当前连接数: " + sessionMap.size());
    }

    /**
     * 收到客户端消息时调用
     */
    @OnMessage
    public void onMessage(String message, @PathParam("sid") String sid) {
        System.out.println("📩 收到消息 [" + sid + "]: " + message);
        // 实现业务逻辑处理
    }

    /**
     * 连接关闭时调用
     */
    @OnClose
    public void onClose(@PathParam("sid") String sid) {
        sessionMap.remove(sid);
        System.out.println("❌ 连接关闭: " + sid);
    }

    /**
     * 向所有客户端广播消息
     */
    public void sendToAllClient(String message) {
        sessionMap.forEach((sid, session) -> {
            try {
                if (session.isOpen()) {
                    session.getBasicRemote().sendText(message);
                }
            } catch (IOException e) {
                System.err.println("发送消息失败: " + e.getMessage());
            }
        });
    }
}
四、结合定时任务实现服务端主动推送
@Component
public class WebSocketTask {

    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 每5秒向所有客户端推送服务器时间
     */
    @Scheduled(fixedRate = 5000) 
    public void sendServerTime() {
        String timeMsg = "服务器时间: " + 
                         LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME);
        webSocketServer.sendToAllClient(timeMsg);
    }

    /**
     * 每天8:30推送业务报表
     */
    @Scheduled(cron = "0 30 8 * * ?")
    public void sendDailyReport() {
        String report = generateDailyReport(); // 生成报表的业务方法
        webSocketServer.sendToAllClient(report);
    }
}
五、客户端连接示例 (JavaScript)
<script>
const socket = new WebSocket('ws://your-domain.com/ws/user123');

// 监听连接建立
socket.onopen = () => {
  console.log('WebSocket连接已建立');
  socket.send('客户端就绪'); // 发送初始消息
};

// 接收服务端消息
socket.onmessage = (event) => {
  console.log('收到服务端消息:', event.data);
  // 更新UI显示
};

// 监听连接关闭
socket.onclose = () => {
  console.log('WebSocket连接已关闭');
};
</script>
六、生产环境最佳实践
  1. 连接管理优化

// 使用线程安全集合
private static final ConcurrentMap<String, Session> sessions = 
    new ConcurrentHashMap<>();

// 添加心跳检测机制
@OnMessage
public void onPong(PongMessage pong, @PathParam("sid") String sid) {
    // 处理心跳响应
}
  1. 消息压缩配置

# application.properties
server.compression.enabled=true
server.compression.mime-types=text/plain,text/html,application/json
  1. 安全加固

// 拦截器验证Token
public class AuthInterceptor extends HttpSessionHandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ...) {
        String token = ((ServletServerHttpRequest) request).getServletRequest().getParameter("token");
        return isValidToken(token); // 自定义验证逻辑
    }
}
  1. 集群支持方案

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer {
    
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        // 使用RabbitMQ作为消息代理
        config.enableStompBrokerRelay("/topic")
              .setRelayHost("rabbitmq-host");
    }
}
七、典型应用场景
  1. 实时监控系统

    • 服务器状态实时推送

    • 业务指标动态更新

  2. 协同办公工具

    • 文档协同编辑

    • 实时白板共享

  3. 金融交易系统

    • 股价实时波动推送

    • 交易指令即时执行

  4. 物联网(IoT)

    • 设备状态实时上报

    • 远程控制指令下发

性能对比:在 1000 并发连接下,WebSocket 比 HTTP 长轮询节省 95% 的带宽,降低 80% 的延迟(数据来源:WebSocket.org 基准测试)

通过 Spring Boot 的简洁实现,WebSocket 为现代 Web 应用提供了真正的实时双向通信能力,完美解决了 HTTP 协议在实时交互场景中的局限性。