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

如何在接收SSE事件时立即终止TIdHTTP.Get()请求及相关问题

关于Indy TIdHTTP处理SSE的终止与连接断开问题

一、如何立即终止GET请求

你当前依赖OnChunkReceived事件触发Abort的方式,只能等待下一个chunk到达才能生效,无法实现“立即”终止。更可靠的方案是直接调用TIdHTTP.Disconnect()方法,同时配合线程状态检查,具体实现如下:

1. 主线程终止逻辑

在主线程中发起终止时,先标记线程为终止状态,再主动断开HTTP连接,最后等待线程退出并释放:

// 主线程调用终止
NotificationThread.Terminated := True;
if Assigned(NotificationThread.HTTP) then
  NotificationThread.HTTP.Disconnect;
NotificationThread.WaitFor;
NotificationThread.Free;

2. 调整线程Execute循环

将原有的repeat...until改为while循环,提前检查终止状态,避免不必要的请求重试:

procedure TAPINotificationThread.Execute;
begin
  HTTP := CreateHTTP;
  var ms := TMemoryStream.Create;
  try
    try
      while not Terminated do
      begin
        try
          HTTP.Get(URL, ms);
        except
          on E: EIdConnClosedGracefully do
            Log('EIdConnClosedGracefully reconnecting...');
          on E: EIdReadTimeout do
            Log('EIdReadTimeout reconnecting...');
          on E: Exception do
            Log('Exception in Notification Thread - ' + E.ClassName + ': ' + E.Message);
        end;
        ms.Clear; // 每次请求后清空流
      end;
    except
      on E: EAbort do
        Log('Notification thread terminating normally');
    end;
  finally
    HTTP.Free;
    ms.Free;
  end;
end;

注意:绝对不要直接在主线程调用Free()释放TIdHTTP组件,这会导致未完成的网络操作访问已释放内存,引发访问违规或资源泄漏。必须先断开连接,等待线程完全退出后再释放资源。

二、服务器每330秒触发EIdConnClosedGracefully的原因

这个异常是服务器主动优雅断开连接导致的,核心原因是服务器端配置了连接超时限制:

  • 多数SSE服务会设置固定的连接时长(330秒=5分30秒是常见配置),防止连接长时间占用服务器资源;
  • 也可能是服务器的反向代理(如Nginx、Apache)或负载均衡器配置了keepalive_timeout、proxy_read_timeout为330秒,超时后主动断开连接;
  • SSE协议本身就要求客户端在连接断开后自动重连,你当前代码中的重连逻辑完全符合规范,无需修改。

额外优化建议

  • 你设置的ReadTimeout为30分钟,远大于服务器的330秒超时,可调整为略大于服务器超时时间(如360秒),避免不必要的长等待;
  • 在OnChunkReceived中检查到Terminated时,可直接调用HTTP.Disconnect()替代Abort,更快触发连接终止;
  • 确保TThread.Queue中的逻辑不会阻塞,避免影响线程的终止响应速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 09:47:42