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

Golang使用SSE长连接被超时关闭,如何仅为SSE接口单独配置超时规则

问题根源

10秒断开的问题和Heroku无关,是Go标准库http.Server的超时配置逻辑导致的:

  • http.Server.WriteTimeout定义的是从请求接收开始到响应完全写完的总时长上限,和中间是否有数据传输无关。哪怕每秒都在发送ping消息,只要总连接时长到了10秒,连接就会被强制断开。
  • ReadTimeout是读取整个请求(包括请求体)的最长时间,对于SSE这类长连接,请求头早就读取完成,但全局配置的ReadTimeout仍会限制总连接时长,这也是你移除该配置后本地运行恢复正常的原因。

分路由配置超时的实现方案

想要保留普通接口的超时安全配置,同时给SSE接口开特例,推荐用http.TimeoutHandler中间件实现路由级的超时控制,不要用全局的ReadTimeout/WriteTimeout配置:

具体实现步骤

  1. 全局http.Server仅保留安全必要的ReadHeaderTimeout配置(用于防范慢请求攻击,不会影响长连接逻辑),移除全局的ReadTimeout和WriteTimeout:
httpServer := &http.Server{
  // 仅限制读取请求头的最长时间,不影响后续长连接
  ReadHeaderTimeout: 5 * time.Second,
}
  1. 所有非SSE的普通接口用http.TimeoutHandler包裹,设置你需要的10秒超时:
// 示例:给普通业务接口加10秒超时
http.Handle("/api/your-common-api", http.TimeoutHandler(yourCommonHandler, 10*time.Second, "request timeout"))
  1. SSE接口无需使用超时中间件,直接注册handler即可不受全局超时限制:
// SSE接口单独注册,无超时限制
http.Handle("/api/sse", sseHandler)

优化建议

当前每秒发送一次ping的频率过高,Heroku的流式响应空闲超时为55秒,你可以调整为每30秒发送一次ping,既能保证连接不会被平台断开,也能减少不必要的带宽和性能消耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:15:05