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

OkHttp连接Spring Boot Stomp WebSocket重连报400错误问题咨询

问题诱因
  • OkHttp默认连接池复用失效TCP连接:OkHttpClient默认连接池最大保留5个空闲TCP连接,存活时间为5分钟。WebSocket应用层关闭后,底层TCP连接未被回收会存入连接池,后续新的WebSocket握手请求复用这些已被服务端判定为无效的旧TCP连接时,服务端会直接返回400错误,且请求不会触发Spring的握手拦截器。你遇到的前3-4次重连正常、之后持续报错的现象,刚好匹配默认连接池的最大空闲连接数阈值。
  • 关闭逻辑时序错误:调用socket.close()是异步操作,你在调用关闭后立刻发起新连接,此时旧WebSocket关联的TCP连接还未完成释放,会残留到连接池中。
  • (可选)请求URL不规范:你示例代码中的WebSocket URL未添加ws:///wss://协议前缀,会导致OkHttp错误复用普通HTTP连接池的连接发起Upgrade请求,也会触发400错误。
解决方案
  1. 补全请求URL协议前缀,同时给WebSocket请求禁用连接复用:
val webSocketRequest = Request.Builder()
    .url("ws://199.166.1.100:8081/websocket") // 补全ws协议头
    .addHeader("Connection", "close") // 强制每次握手使用新的TCP连接,不复用连接池资源
    .build()
  1. 给WebSocket专用的OkHttpClient单独配置连接池,直接禁用空闲连接保留:
// 初始化WebSocket专属OkHttpClient,不复用TCP连接
val wsOkHttpClient = OkHttpClient.Builder()
    .connectionPool(ConnectionPool(0, 1, TimeUnit.NANOSECONDS)) // 空闲连接数为0,立即回收失效连接
    .build()
  1. 调整重连触发时机:不要在调用socket.close()后立刻发起新连接,将重连逻辑放到onClosed回调中执行,确保旧连接资源完全释放后再发起新的握手请求。
  2. 可选升级OkHttp版本到4.10.0及以上,规避旧版本WebSocket连接管理的已知bug。

内容的提问来源于stack exchange,提问作者KisungTae

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 16:54:02