You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Spring Boot的WebSocket服务器遇畸形数据包后无响应问题求助

解决方案:修复Spring Boot WebSocket因异常客户端导致的服务瘫痪问题

这个问题的核心是你的WebSocket Handler没有正确管理活跃会话列表,也未处理消息发送时的异常情况。当cwebsocket客户端异常关闭会话后,无效会话仍留在你的广播列表中,后续尝试向其发送消息会抛出未捕获的异常,进而中断Spring的WebSocket处理链,最终导致整个WebSocket服务无法响应新连接。

具体修复步骤

  1. 移除已关闭的会话:重写afterConnectionClosed方法,从会话列表中移除关闭的连接,避免后续遍历到无效会话
  2. 发送前校验会话状态:在广播消息前,先检查会话是否处于活跃(isOpen())状态,跳过无效会话
  3. 捕获发送异常:对每个会话的消息发送操作单独捕获异常,防止单个会话的失败影响整个广播流程

修改后的SocketHandler.java代码

import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.concurrent.CopyOnWriteArrayList;
import java.util.List;
import java.io.IOException;

@Component
public class SocketHandler extends TextWebSocketHandler {
    List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws InterruptedException {
        // 遍历所有活跃会话,发送消息
        for(WebSocketSession webSocketSession : sessions) {
            // 先检查会话是否处于打开状态
            if (webSocketSession.isOpen()) {
                try {
                    webSocketSession.sendMessage(message);
                } catch (IOException e) {
                    // 捕获单个会话的发送异常,避免影响其他会话
                    e.printStackTrace();
                    // 可选:如果发送失败,直接移除该会话
                    sessions.remove(webSocketSession);
                }
            } else {
                // 移除已关闭的会话
                sessions.remove(webSocketSession);
            }
        }
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
    }

    // 新增:会话关闭时从列表中移除
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
        super.afterConnectionClosed(session, status);
    }
}

修复原理说明

  • 会话生命周期管理:通过afterConnectionClosed主动清理无效会话,避免列表中积累大量已关闭的连接
  • 前置状态校验:isOpen()检查可以提前过滤掉无效会话,减少不必要的发送操作和异常
  • 异常隔离:单个会话的发送异常被捕获后,不会中断整个广播流程,保证其他正常客户端不受影响
  • 额外容错:即使发送时出现异常,也会移除该会话,防止后续重复尝试发送到无效连接

修改后,即使cwebsocket客户端发送畸形数据包导致会话异常关闭,服务器也能正确清理无效会话,后续的HTML/JS客户端或其他客户端依然可以正常建立WebSocket连接并接收消息,不会出现服务瘫痪的情况。

内容的提问来源于stack exchange,提问作者Gábor Paller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:45:48