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

Erlang Cowboy EventSource每隔60秒断开重连问题求助

解决Cowboy EventSource示例频繁断开重连(ERR_INCOMPLETE_CHUNKED_ENCODING)的问题

先给你吃个定心丸:这绝对不是SSE标准内置的定期断开机制——SSE只会遵循你设置的retry字段调整重连间隔,不会默认搞60秒强制断开这套操作。结合你碰到的ERR_INCOMPLETE_CHUNKED_ENCODING错误,大概率是某个中间环节的超时配置在搞鬼,我给你梳理几个排查方向:

1. 检查反向代理的超时设置(如果用了Nginx/Apache)

很多人跑Cowboy时会套一层反向代理,而Nginx默认的proxy_read_timeout刚好是60秒——完美匹配你的断开间隔!如果是这种情况,修改Nginx配置:

location /eventsource {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_read_timeout 3600s; # 把超时时间调大,比如1小时
}

proxy_http_version 1.1和proxy_set_header Connection ""是为了保持HTTP/1.1的长连接特性,避免代理主动断开SSE连接。

2. 调整Cowboy自身的连接超时配置

如果没用到反向代理,就得看看Cowboy的服务器配置。默认情况下Cowboy可能有较短的空闲超时设置,你需要在监听器或者路由配置里把超时时间拉满:
在启动Cowboy的代码里,调整timeout参数(单位是毫秒):

{ok, _} = cowboy:start_clear(
    my_http_listener,
    [{port, 8080}],
    #{env => #{dispatch => Dispatch},
      timeout => 3600000} % 设置为1小时的超时
)

这样能避免Cowboy服务器主动断开长时间空闲的SSE连接。

3. 添加SSE心跳包防止中间设备断开

即使服务器和代理都没设超时,路由器、防火墙这类中间设备也可能因为长时间没数据传输而主动断开连接。这时候你需要给SSE加心跳包——每隔一段时间发送一个空事件,保持连接活跃:
在Cowboy的EventSource处理函数里,加个定时任务,比如每30秒发一次空事件:

send_heartbeat(Req, State) ->
    timer:sleep(30000),
    {ok, Req2} = cowboy_req:send_events([""], Req, State),
    send_heartbeat(Req2, State).

启动这个心跳函数,就能让连接一直保持活跃,避免中间设备误判为空闲连接断开。

4. 排查系统TCP层的超时设置

最后可以检查Debian系统的TCP keepalive配置,看看是不是系统层面的超时在搞鬼:
用命令查看当前设置:

sysctl net.ipv4.tcp_keepalive_time

如果这个值小于60秒(一般默认是7200秒,也就是2小时),那可能需要调整:

sysctl -w net.ipv4.tcp_keepalive_time=3600

或者写入/etc/sysctl.conf让设置永久生效。

按照这个顺序排查下来,应该能解决你碰到的60秒断开问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 17:17:49