Delphi Indy平替的HTTP/HTTPS组件,TSynHttpClient全解析

简介: TSynHttpClient是基于Synapse深度优化的Delphi工业级HTTP/HTTPS库,支持Delphi 7+跨版本、TLS 1.2/1.3全平台兼容;具备防卡死超时、智能SNI、真Keep-Alive、自动UTF-8转换与错误日志Dump等特性,仅需2个DLL即可稳定调用99% HTTPS

TSynHttpClient 工业级 HTTP/HTTPS 封装库

📖 1. 模块简介

TSynHttpClient 是基于 Ararat Synapse 网络库二次封装的高性能、跨版本的 HTTP/HTTPS 通讯类,针对Delphi做了一系列深度优化。

🌟 核心特性:

  • 跨版本完美兼容:利用 {$IFDEF UNICODE} 宏,底层自动抹平 Delphi 7 以上的版本差异,彻底杜绝中文与 JSON 乱码。
  • 无视系统底层限制:摆脱 Delphi 自带 WinInet 对 TLS 1.2/1.3 的限制,在 Windows XP 到 Win11 上完美握手现代 HTTPS 接口。
  • 强力防卡死机制:底层强制干预 TCP 建连与读写超时,彻底解决 DNS 解析阻塞或网络断开导致的主线程假死。
  • 智能 SNI 注入:针对多租户环境,自动注入 HTTPS SNI 域名,防止网关返回 500 或 403 误杀。
  • 极致复用 (Keep-Alive):支持真正的 TCP/TLS 长连接复用,在批量数据上传场景下,可免除反复握手,性能提升高达 10 倍。
  • 自动异常留痕:内置自动日志引擎,遇到 4xx、5xx 或网络底层的 Socket 错误时,自动保存详尽的报文 Dump,极大降低排错难度。
  • 2个dll打天下:本项目内置的 libcrypto-1_1.dll 和 libssl-1_1.dll,可以满足 99% 以上的 HTTPS API 接口调用需求。无需像老的 TIdHTTP 那样区分版本。
  • 真实的超时时间控制:区别于TIDHTTP以及Windows系统内置的组件,TSynHttpClient有真实有效的超时时间。

⚙️ 2. 核心依赖与环境配置

本组件的 HTTPS 核心加密能力由 OpenSSL 1.1.1 提供。在使用前,必须处理好动态库依赖。

📦 2.1 必须的 DLL 文件

在发布或运行程序时,必须确保环境中有以下两个 32 位(x86)的动态链接库(非HTTPS请求不需要这两个DLL):

  • libcrypto-1_1.dll (提供基础密码学算法)
  • libssl-1_1.dll (提供 TLS 1.2 / 1.3 协议栈)

(建议使用采用 /MT 静态编译的 Win32 XP 兼容版,单文件大小在 2.5MB 左右,能免除对 VC++ 运行库的依赖。)

🔍 2.2 Synapse 自动搜索路径规则

Synapse 在初始化 HTTPS 请求时,会自动调用 Windows API 去寻找这 2 个 DLL,查找顺序如下(从上到下,找到即停止):

  1. 当前进程的内存中(如果主程序启动时已经用 LoadLibrary 提前加载过)。
  2. 程序执行文件 (.exe) 所在的当前根目录(⭐ 最推荐的做法)。
  3. Windows 系统目录(C:\Windows\System32 或 SysWOW64)。
  4. 系统环境变量 PATH 中包含的任意目录。

防坑警告:为了防止被其他软件残缺版本的 DLL 劫持,请务必把这两个 DLL 和你的 EXE 放在同一个文件夹下。


🛠️ 3. 类参考手册 (Class Reference)

3.1 实例化与生命周期

var Client: TSynHttpClient;
Client := TSynHttpClient.Create; // 创建并自动初始化默认参数
Client.ResetSynHttp;           // 重置状态(如果在循环中复用 Client 且需要改配置,可调用此方法)
Client.Free;                     // 销毁实例,并自动安全关闭底层的 TCP/Socket 通道

3.2 常用属性 (配置类)

属性名 类型 默认值 描述
Timeout Integer 15000 (15秒) 网络建连与数据读写超时时间(毫秒)。此超时时间是真实有效受控的。
KeepAlive Boolean False 长连接开关。设为 True 时,TCP/TLS 通道在请求后不关闭。仅在高频批处理场景下开启,单次交互请保持 False。
Protocol string '1.1' HTTP 协议版本。强制使用 1.1 以支持长连接分块等现代特性。
MimeType string 'application/json' 决定 Content-Type 的值。请求 WebService 时可改为 text/xml; charset=utf-8。
UserAgent string 现代 Chrome 标识 伪装浏览器,防止被国内政务 WAF 视为爬虫直接拦截。
ProxyHost string '' 代理服务器 IP(如需抓包或穿透内网,填入代理IP,如 127.0.0.1)。
ProxyPort string '' 代理服务器端口(如 7890)。
AutoUTF8 Boolean True 防乱码开关。发送和接收时自动在本地编码与 UTF-8 之间双向转换。
SaveLog Boolean True 遇到非 200~299 或网络断开时,是否自动写 .txt 日志到本地。
CustomHeaders TStringList TStringList.Create 动态添加额外请求头参数,如 Token 或签名。

3.3 方法 (Method)

  • function SynDoGet(const AURL: string): Boolean;
    发起 GET 请求。
  • function SynDoPost(const AURL, AJsonOrFormBody: string): Boolean;
    发起 POST 请求,第二个参数传入 JSON 或 XML 字符串。
  • procedure AddCustomHeaders(sKey, sValue: string);
    向请求头中动态添加参数,如 Token 或签名。示例:Client.AddCustomHeaders('Authorization', 'Bearer 123');

3.4 结果属性 (只读,调用后获取)

⚠️ 【极其重要】: 认清三个判断标准的区别

  1. SynDoPost 的返回值 (Boolean):代表网络物理层是否通畅(底层 Socket 是否报错)。
  2. StatusCode:代表服务端收到了请求并返回的真实 HTTP 状态码(如 200, 400, 401, 500)。
  3. BusiSuccess:代表业务逻辑是否成功(仅当 StatusCode 在 200~299 之间且Sock.LastError 为 0 时为 True)。
属性名 类型 描述
BusiSuccess Boolean 业务成功标志。当 200 <= StatusCode < 300 且无报错时为 True。
ErrorMessage string 前端展示神器:如果是断网,返回底层 Socket 错误;如果是服务器报 500,返回服务端吐出的 JSON 错误信息。
ResponseStr string 服务器返回的响应体内容(已根据 AutoUTF8 自动解码为不乱码的本地字符串)。
StatusCode Integer HTTP 状态码。
LastError Integer 底层 Windows Socket 错误码(如 10061 拒绝连接,10060 超时)。

💻 4. 典型业务场景实战代码

场景 1:最基础的 GET/POST 请求 (保持 KeepAlive=False)

适用场景:用户点击界面按钮查询单笔数据。

procedure TForm1.BtnPostClick(Sender: TObject);
var
  Client: TSynHttpClient;
begin
  Client := TSynHttpClient.Create; // 默认 KeepAlive=False,用完即焚最安全
  try
    Client.Timeout := 5000;
    Client.AddCustomHeaders('Signature', 'ABCDEF123456');

    Client.SynDoPost('https://opendata.baidu.com/api.php?query=114.114.114.114&co=&resource_id=6006&oe=utf8', '{"a":"a"}');

    if Client.BusiSuccess then
      ShowMessage('交易成功!平台返回:' + Client.ResponseStr)
    else
      ShowMessage('交易失败:' + Client.ErrorMessage); // 自动显示网络错误或服务器JSON报错
  finally
    Client.Free;
  end;
end;

procedure TForm1.BtnGetClick(Sender: TObject);
begin
  with TSynHttpClient.Create do
  try
    ResetSynHttp;
    Timeout := 3000; //缺省值=15000 此处可动态修改,且稳定生效
    SynDoGet(Trim(https://opendata.baidu.com/api.php?query=114.114.114.114&co=&resource_id=6006&oe=utf8?a=1614840052));
    if BusiSuccess then //业务成功
    begin
      //解析业务数据
      ShowMessage('业务成功:' + #13#10 + ResponseStr);
    end else
    begin
      ShowMessage('业务失败:' + #13#10 + ErrorMessage);
    end;
  finally
    Free;
  end;
end;

procedure TForm1.ButtonformClick(Sender: TObject);
var
  sSendData, sUrl: string;
begin
  with TSynHttpClient.Create do
  try
    ResetSynHttp;
    Timeout := 3000; //缺省值=15000 此处可动态修改,且稳定生效
    MimeType := 'application/x-www-form-urlencoded';
    sUrl := 'https://api.totalshiftleft.ai/openapi/pay/query';
    sSendData := 'mch_id=000001' + '&' +
                 'nonce_str=02hsddhdh' + '&' +
                 'a=1614840052' + '&' +
                 'billno=000000001';
    SynDoPost(sUrl, sSendData);
    if BusiSuccess then //接口调用成功
    begin
      //解析业务数据
      ShowMessage('业务成功:' + #13#10 + ResponseStr);
    end else
    begin
      ShowMessage('业务失败:' + #13#10 + ErrorMessage);
    end;
  finally
    Free;
  end;
end;

场景 2:调用传统的 WebService (SOAP XML)

无需使用 Delphi 笨重的 WSDL 导入器,直接利用本类发送文本即可,HTTP/HTTPS 都支持!

procedure TForm1.BtnSoapClick(Sender: TObject);
var
  Client: TSynHttpClient;
  SoapBody: string;
begin
  Client := TSynHttpClient.Create;
  try
    Client.MimeType := 'text/xml; charset=utf-8';
    <!-- Client.AddCustomHeaders('SOAPAction', '"http://tempuri.org/GetPersonInfo"'); -->

    SoapBody := '<?xml version="1.0" encoding="utf-8"?><soap:Envelope ...><a>1614840052</a></soap:Envelope>';

    if Client.SynDoPost('https://demo.totalshiftleft.ai/soap?wsdl', SoapBody) then
    begin
      if Client.BusiSuccess then
         ShowMessage('WebService 调用成功: ' + Client.ResponseStr);
    end;
  finally
    Client.Free;
  end;
end;

🔥 场景 3:极速批处理 (开启 KeepAlive = True)

适用场景:每天凌晨定时向Restful密集上传成千上万条记录。

为什么要开? 如果上传 10000 次,开启 KeepAlive 可以省去 10000 次 TCP 握手和 TLS 证书协商时间,耗时从几十分钟骤降至几分钟!

procedure TForm1.BatchUpload;
var
  Client: TSynHttpClient;
  i: Integer;
begin
  Client := TSynHttpClient.Create;
  try
    // 1. 开启极速长连接模式
    Client.KeepAlive := True;  
    Client.Timeout := 3000; //缺省值=15000 此处可动态修改,且稳定生效
    Client.MimeType := 'application/json';
    Client.AddCustomHeaders('Authorization', 'Bearer XXXX');
    Client.AddCustomHeaders('a', '1614840052');

    // 2. 在一个循环中,复用同一个 Client 实例高频发送
    for i := 1 to 10000 do
    begin
      Client.SynDoPost('https://api.example.com/upload', '{"id":' + IntToStr(i) + '}');

      if not Client.BusiSuccess then
        Log('第' + IntToStr(i) + '条失败: ' + Client.ErrorMessage);
    end;

  finally
    // 3. 循环结束,Free 时自动发送 FIN 包优雅断开 TCP 通道
    Client.Free;
  end;
end;

🚦 5. 高阶排坑指南:KeepAlive (长连接) 的正确使用姿势

针对 KeepAlive 属性,请团队研发人员务必牢记以下设计规范:

  1. 绝对不要在低频 UI 交互中开启它:
    如果你的请求是用户手动点击触发的,或者两次请求的间隔超过 10 秒钟,必须使用默认的 KeepAlive = False。因为现代服务器网关 (如 Nginx) 通常会在 60 秒闲置后单方面悄悄掐断连接。如果在低频场景滥用长连接,极易引发底层报 10054 Connection reset by peer 的玄学错误。
  2. KeepAlive 生死权在服务端:
    HTTP 的 KeepAlive 超时时间由服务端网关控制(而不是客户端)。客户端的任务就是在高频 for 循环中复用通道榨干性能,用完后立即释放。
  3. 每次请求自动刷新机制:
    本类在底层已经做了“脏头清洗”机制。在长连接 for 循环期间,无需担心上一次请求的服务端响应头会污染下一次的请求头,直接调用 SynDoPost 即可。
  4. 自动重连策略:
    Keep-alive模式下,无需担心长连接断开,Synapse在每次请求前会向操作系统咨询当前通道是否可读,如果不可读会重新建立通道并进行TCP和TLS握手。

📁 6. 自动错误日志追踪 (Troubleshooting)

为了解决实施人员在客户现场难以复现网络故障的问题,组件内置了 SaveHttpErrLogs 功能。

当满足以下条件时,组件会自动触发写日志:

  1. SaveLog = True(默认开启)
  2. 业务未成功(BusiSuccess = False),即网络断开、超时,或者服务端返回了 400、500 等错误。

存放路径:
日志会自动存放在程序同目录下的 SynHttpLogs 文件夹中。按天分文件,如 20260825.txt。

日志内容解析(示例):

------------------<2026-8-25 17:1:22:845>---------------------
<URL>https://xxxxx/api.php?query=114.114.114.114&co=&resource_id=6006&oe=utf8</URL>
<RequestHeader>Host: xxxx</RequestHeader>
<RequestBody>{"apikey": "xx","id": 10001}</RequestBody>
<HTTPMethod>POST</HTTPMethod>
<StatusCode>400</StatusCode>
<StatusText>Bad Request</StatusText>
<ResponseBody>HTTP Error 400. The request has an invalid header name.</ResponseBody>
<Remote>opendata.baidu.com</Remote>
<LastError>0</LastError>
------------------<2026-8-25 17:1:22:845>---------------------

(通过该日志,研发人员可以直接还原发出的确切头部和 Body,快速排查是传参错误、网络错误还是服务端挂机。)

7. 集成模块到现有项目

  1. 拷贝”ssllib“文件夹到项目根目录下面,然后在工程文件夹中Search Path中添加”ssllib“文件夹的路径。
  2. 在需要使用的单元中uses utXrxHttps 即可。

❤️ ~~~~~~~~~~~~~

相关文章
|
18天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
8625 25
|
17天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
3072 14
|
16天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
2115 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
5天前
|
人工智能 JSON Linux
【全网最详细】ComfyUI使用教程:下载+本地部署+配置+工作流搭建一篇搞定(2026最新版)
ComfyUI是一款免费开源的本地AI绘图工具,采用节点式工作流设计,支持文生图、图生图、局部重绘、放大、换脸等多种功能。可离线运行,依赖显卡加速,无需联网。支持自定义流程保存与分享,插件生态丰富,适合进阶用户。(239字)
|
17天前
|
云安全 人工智能 安全
|
11天前
|
人工智能 Linux 开发者
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
Codex是OpenAI推出的AI编程智能体,可读取本地项目、理解需求并自动修改代码。支持桌面GUI、命令行(CLI)及VS Code/Cursor插件三种形态,覆盖可视化操作、终端高效开发与编辑器无缝集成场景,助开发者用自然语言驱动编码全流程。(239字)
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
|
11天前
|
人工智能 JSON 编解码
【2026最新版】ComfyUI本地部署教程,新手也能看懂!
ComfyUI是本地运行的AI绘画工具,采用节点式工作流设计:通过拖拽连接“加载模型”“提示词编码”“采样”“解码”等模块,实现高度可控的文生图。新手推荐使用秋叶整合包,一键启动、内置模型管理与插件安装器,轻松上手。(239字)