有些缺陷每次都会出现,有些则按照某种规律出现。2026.9 版本修复的 Huobi 和 HTX 签名缺陷属于后一种,这也正是它更难定位的原因:在非 UTC 时区运行的主机上,私有请求在每天的部分时段会失败,其余时段则一切正常,这看起来完全就是间歇性的身份验证问题,直到有人注意到这种规律恰好与时钟对应为止。
由两个不同时钟拼出的时间戳
Huobi 和 HTX 都要求签名请求携带一个 UTC 时间戳,格式为 yyyy-MM-ddTHH:mm:ss。TsgcWSAPI_Huobi 和 TsgcWSAPI_HTX 共用的签名例程 TsgcWS_API_Huobi_Base,此前是用两个不同的来源来拼出这个时间戳的:日期部分取自本地系统时钟,时间部分取自 UTC。在大多数机器上,一天中的大部分时间里,本地日期和 UTC 日期是同一个值,所以看不出任何问题。而在接近 UTC 午夜、且本地时区偏移使其跨越了这一边界的主机上,日期和时间就不再一致,Huobi 在其自己一侧计算出的签名与之不匹配,请求因此被拒绝。
修复方案让日期和时间都取自同一个 UTC 值:
uses
sgcBase_Helpers;
var
vUTC: TDateTime;
vTimeStamp: string;
begin
vUTC := sgcGetDateTimeAsUTC;
vTimeStamp := FormatDateTime('yyyy-mm-dd', vUTC) + 'T' +
FormatDateTime('hh:nn:ss', vUTC);
end;
无需任何配置。TsgcWSAPI_Huobi 和 TsgcWSAPI_HTX 都调用同一个签名例程,因此两者会同时得到修复:
uses
sgcWebSocket, sgcWebSocket_APIs;
var
oHuobi: TsgcWSAPI_Huobi;
begin
oHuobi := TsgcWSAPI_Huobi.Create(nil);
oHuobi.Client := oClient;
oHuobi.Huobi.ApiKey := 'your_api_key';
oHuobi.Huobi.ApiSecret := 'your_api_secret';
oClient.Active := True;
// Authentication now signs with a timestamp taken entirely from UTC.
oHuobi.SubscribeOrderUpdates('btcusdt');
end;
如果你的日志显示 Huobi 或 HTX 的私有请求时断时续地失败,且没有明显的触发规律,这很可能就是原因所在,尤其是当你的服务器不运行在 UTC 时区时。
重连后私有订阅丢失
Huobi 同时也是受另一个重连缺陷影响的多个交易所客户端之一,该缺陷已在同一批修复中一并解决:WatchDog 重连之后,私有订阅(订单、余额、成交)不会被重新订阅。重连本身是成功的,日志也如实记录为成功,因此完全看不出断线前你所接收的私有数据流已经悄悄消失。现在,这部分重新订阅已经并入了重连后恢复公共行情订阅所使用的同一条重订阅路径。
升级说明
这两项修复都是即装即用的。无需设置任何属性,也无需修改任何代码,签名现在就是正确的,重连后的重新订阅现在也包含了你的私有订阅。
有疑问、需要反馈,或需要迁移方面的协助?联系我们—你收到的回复将来自亲自编写这些代码的人。
