
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请求不需要这两个DLLlibcrypto-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查找顺序如下从上到下找到即停止当前进程的内存中如果主程序启动时已经用LoadLibrary提前加载过。程序执行文件 (.exe) 所在的当前根目录⭐最推荐的做法。Windows 系统目录C:\Windows\System32或SysWOW64。系统环境变量PATH中包含的任意目录。防坑警告为了防止被其他软件残缺版本的 DLL 劫持请务必把这两个 DLL 和你的 EXE 放在同一个文件夹下。️ 3. 类参考手册 (Class Reference)3.1 实例化与生命周期var Client: TSynHttpClient; Client : TSynHttpClient.Create; // 创建并自动初始化默认参数 Client.ResetSynHttp; // 重置状态如果在循环中复用 Client 且需要改配置可调用此方法 Client.Free; // 销毁实例并自动安全关闭底层的 TCP/Socket 通道3.2 常用属性 (配置类)属性名类型默认值描述TimeoutInteger15000(15秒)网络建连与数据读写超时时间毫秒。此超时时间是真实有效受控的。KeepAliveBooleanFalse长连接开关。设为 True 时TCP/TLS 通道在请求后不关闭。仅在高频批处理场景下开启单次交互请保持 False。Protocolstring1.1HTTP 协议版本。强制使用 1.1 以支持长连接分块等现代特性。MimeTypestringapplication/json决定Content-Type的值。请求 WebService 时可改为text/xml; charsetutf-8。UserAgentstring现代 Chrome 标识伪装浏览器防止被国内政务 WAF 视为爬虫直接拦截。ProxyHoststring代理服务器 IP如需抓包或穿透内网填入代理IP如127.0.0.1。ProxyPortstring代理服务器端口如7890。AutoUTF8BooleanTrue防乱码开关。发送和接收时自动在本地编码与 UTF-8 之间双向转换。SaveLogBooleanTrue遇到非 200~299 或网络断开时是否自动写.txt日志到本地。CustomHeadersTStringListTStringList.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 结果属性 (只读调用后获取)⚠️【极其重要】: 认清三个判断标准的区别SynDoPost的返回值 (Boolean)代表网络物理层是否通畅底层 Socket 是否报错。StatusCode代表服务端收到了请求并返回的真实 HTTP 状态码如 200, 400, 401, 500。BusiSuccess代表业务逻辑是否成功仅当 StatusCode 在 200~299 之间且Sock.LastError 为 0 时为 True。属性名类型描述BusiSuccessBoolean业务成功标志。当200 StatusCode 300且无报错时为 True。ErrorMessagestring前端展示神器如果是断网返回底层 Socket 错误如果是服务器报 500返回服务端吐出的 JSON 错误信息。ResponseStrstring服务器返回的响应体内容已根据AutoUTF8自动解码为不乱码的本地字符串。StatusCodeIntegerHTTP 状态码。LastErrorInteger底层 Windows Socket 错误码如10061拒绝连接10060超时。 4. 典型业务场景实战代码场景 1最基础的 GET/POST 请求 (保持 KeepAliveFalse)适用场景用户点击界面按钮查询单笔数据。procedure TForm1.BtnPostClick(Sender: TObject); var Client: TSynHttpClient; begin Client : TSynHttpClient.Create; // 默认 KeepAliveFalse用完即焚最安全 try Client.Timeout : 5000; Client.AddCustomHeaders(Signature, ABCDEF123456); Client.SynDoPost(https://opendata.baidu.com/api.php?query114.114.114.114coresource_id6006oeutf8, {QQ:1614840052}); 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?query114.114.114.114coresource_id6006oeutf8?QQ1614840052)); 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_id000001 nonce_str02hsddhdh qNumber1614840052 billno000000001; 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; charsetutf-8; !-- Client.AddCustomHeaders(SOAPAction, http://tempuri.org/GetPersonInfo); -- SoapBody : ?xml version1.0 encodingutf-8?soap:Envelope ...qq1614840052/qq/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(contact, 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属性请团队研发人员务必牢记以下设计规范绝对不要在低频 UI 交互中开启它如果你的请求是用户手动点击触发的或者两次请求的间隔超过 10 秒钟必须使用默认的KeepAlive False。因为现代服务器网关 (如 Nginx) 通常会在 60 秒闲置后单方面悄悄掐断连接。如果在低频场景滥用长连接极易引发底层报10054 Connection reset by peer的玄学错误。KeepAlive 生死权在服务端HTTP 的 KeepAlive 超时时间由服务端网关控制而不是客户端。客户端的任务就是在高频for循环中复用通道榨干性能用完后立即释放。每次请求自动刷新机制本类在底层已经做了“脏头清洗”机制。在长连接for循环期间无需担心上一次请求的服务端响应头会污染下一次的请求头直接调用SynDoPost即可。自动重连策略Keep-alive模式下无需担心长连接断开Synapse在每次请求前会向操作系统咨询当前通道是否可读如果不可读会重新建立通道并进行TCP和TLS握手。 6. 自动错误日志追踪 (Troubleshooting)为了解决实施人员在客户现场难以复现网络故障的问题组件内置了SaveHttpErrLogs功能。当满足以下条件时组件会自动触发写日志SaveLog True默认开启业务未成功BusiSuccess False即网络断开、超时或者服务端返回了 400、500 等错误。存放路径日志会自动存放在程序同目录下的SynHttpLogs文件夹中。按天分文件如20260825.txt。日志内容解析示例------------------2026-8-25 17:1:22:845---------------------URLhttps://opendata.baidu.com/api.php?query114.114.114.114coresource_id6006oeutf8/URLRequestHeaderHost: opendata.baidu.com/RequestHeaderRequestBody{apikey: xx,id: 10001}/RequestBodyHTTPMethodPOST/HTTPMethodStatusCode400/StatusCodeStatusTextBad Request/StatusTextResponseBodyHTTP Error 400. The request has an invalid header name./ResponseBodyRemoteopendata.baidu.com/RemoteLastError0/LastError------------------2026-8-25 17:1:22:845---------------------(通过该日志研发人员可以直接还原发出的确切头部和 Body快速排查是传参错误、网络错误还是服务端挂机。)7. 集成模块到现有项目拷贝”ssllib“文件夹到项目根目录下面然后在工程文件夹中Search Path中添加”ssllib“文件夹的路径。在需要使用的单元中uses utXrxHttps 即可。❤️ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~